天天看點

web程式的統一認證實作:filter操作

現在web程式很多都用到統一認證這東西,剛好看《jsp2.0技術手冊》看到這塊,看完感覺有點模糊,是以就自己寫代碼試了一下,花了好長一段時間,原因終于在今天找到了,并且成功解決,但是我并沒有是以而感到自豪,因為我越來越感覺自己蠢了,蠢得無可救藥。廢話不說了,看下面的東西吧:

  用filter實作統一認證我用了5個頁面,分别為:login.jsp,filter2.jsp,filter3.jsp,LoginCheck.java,SessionCheck.java.其中最主要的是SessionCheck.java.另外還需要配置web.xml檔案,這個千萬不能忘記哦。

  下面是我的web程式的結構圖:

web程式的統一認證實作:filter操作

下面看下各個頁面的代碼(内含很多注釋,友善了解):

SessionCheck.java:

1 package filter;  

2   

3 import java.io.IOException;  

4 import javax.servlet.Filter;  

5 import javax.servlet.FilterChain;  

6 import javax.servlet.FilterConfig;  

7 import javax.servlet.ServletContext; 

8 import javax.servlet.ServletException; 

9 import javax.servlet.ServletRequest;

10 import javax.servlet.ServletResponse; 

11 import javax.servlet.http.HttpServletRequest; 

12 import javax.servlet.http.HttpServletResponse; 

13 import javax.servlet.http.HttpSession; 

14  

15  

16 public class SessionCheck implements Filter {

17     

18     private ServletContext context;

19     private String targetUri; 

20 

21     public void destroy() { 

22         // TODO Auto-generated method stub 

23          

24     } 

25  

26     public void doFilter( 

27             ServletRequest request,  

28             ServletResponse response, 

29             FilterChain chain) throws IOException, ServletException { 

30         // TODO Auto-generated method stub 

31         HttpServletRequest httpRequest = (HttpServletRequest)request; 

32         HttpServletResponse httpResponse = (HttpServletResponse) response; 

33         /** 

34          * getSession(false)此方法如果得不到session,也不會自動建立一個session 

35          *  

36          * 插曲:看到getSeesion(false)表示之前沒看到過,不知道意思,本能的猜測是: 

37          * 如果沒有得到sesson,則傳回null,如果參數為true,得不到session那就重新建立一個 

38          * 因為隻是猜測,是以上csdn查了下,結果看到一文章,說的果斷和我的了解相反,

              接着看,下面各種各樣的回複,琳琅滿目 

39          * 當然,在找之前已經用debug驗證過了,我的想法隻要不是驗證方法錯了那我的了解肯定是對的 

40          * 結果在csdn看到幾乎一樣的問題,而且一樓回答剛好跟我的完全相反,并且樓主還給了30分,這讓我不由的蛋疼了下,

41          * 結論完全相反呀,繼續忐忑的往下看,一哥們什麼都沒解釋,直接把關于session的官方文檔給拉出來貼着,全英文,還好哥雖然沒過6雞

42          * 但也還是能看懂幾個abc的,意思跟我了解一樣,忐忑的心終于有點放下了,繼續往下看,一看id,俨然是樓主本人,一看内容,我熱淚盈眶 

43          * 樓主你Y真是好人啊,一樓了解完全相反你Y居然給30分,你妹啊,害得我還猶豫了半天,納悶了半天,不過還好你出來糾正了你之前的 

44          * NC行徑,也算是一大進步。 

45 */ 

46         HttpSession session = httpRequest.getSession(false);

47          

48         if(session != null){

49             String passed = (String)session.getAttribute("passed"); 

50             if("true".equals(passed)){ 

51                 chain.doFilter(httpRequest, httpResponse);

52                 /** 

53                  * return 說明filter在執行了chain.doFilter之後會傳回來繼續執行原先的filter

54                  * 相當于一個遞歸調用 

55                  * return 下面的代碼表示執行失敗的情況 

56 */

57                 return; 

58             }else if("passing".equals(passed)){ 

59                 /** 

60                  * httpRequest.getRequestURL()擷取絕對路徑

61                  * 例如http://127.0.0.1:8088/webTest/filter1/login.jsp 

62                  *  

63                  * httpRequest.getRequestURI()擷取相對路徑。 

64                  * /webTest/filter/LoginCheck,其中filter/LoginCheck為jsp頁面中form表單的action值

65                  * 對應的Servlet的<url-pattern>要寫成/filter/LoginCheck 66 */

67                 if("/webTest/filter/LoginCheck".equals(new String(httpRequest.getRequestURI()))){ 

68                     chain.doFilter(httpRequest, httpResponse); 

69                     return; 

70                 }

71             } 

72             /** 

73              * 如果之前的filter執行均失敗,則說明這個session中的passed認證已經是錯誤的,必須删除 

74 */ 

75             session.removeAttribute("passed"); 

76         } 

77         /** 

78          * requestUrl儲存目前請求的url 

79          * query儲存目前請求下的參數 

80 */

81         StringBuffer requestUrl = new StringBuffer(httpRequest.getRequestURI());

82         String query = httpRequest.getQueryString(); 

83         if(null != query){ 

84             requestUrl.append(query); 

85         }

86         /**

87          * 設定request範圍内的originalUri(認證之前的請求位址),用于在login頁面擷取,并可以通過隐藏參數的形式把這個值傳遞到LoginCheck 

88          * 當登入之後就可以直接轉到login認證之前的頁面 

89 */ 

90         httpRequest.setAttribute("originalUri", new String(requestUrl));

91         httpRequest.getRequestDispatcher(targetUri).forward(httpRequest, httpResponse); 

92     } 

93  

94     public void init(FilterConfig config) throws ServletException { 

95         // TODO Auto-generated method stub 

96         this.context = config.getServletContext(); 

97         /** 

98          * 擷取filter的初始化參數,當需要認證的時候都會跳轉到targetUri指定頁面,一般都是登入頁面

99 */

100         this.targetUri = config.getInitParameter("targetUri");

101     }

102 

103 

104 }

      LoginCheck.java:

1 package filter; 

2  

3 import java.io.IOException;

4 import javax.servlet.ServletException;

5 import javax.servlet.http.HttpServlet;

6 import javax.servlet.http.HttpServletRequest;

7 import javax.servlet.http.HttpServletResponse;

8 import javax.servlet.http.HttpSession; 

10 public class LoginCheck extends HttpServlet {

11     

12     private static final long serialVersionUID = -4075113258177758412L;

13    

14     protected void doPost(HttpServletRequest request,HttpServletResponse response)

15         throws IOException,ServletException{

16         String user = request.getParameter("user");

17         String pwd = request.getParameter("pwd");

18         String targetUri = request.getParameter("originalUri");

19         

20         if(!"LH123".equals(user) || !"123LH".equals(pwd)){

21             System.out.println("認證失敗");

22             throw new ServletException("認證失敗");

23         }

24         /**

25          * 認證成功的情況

26 */

27         HttpSession session = request.getSession();

28         session.setAttribute("passed", "true");

29         request.setAttribute("user", user);

30         request.setAttribute("pwd", pwd);

31         if(!"".equals(targetUri)){

32             /**

33              * SessionCheck中儲存入的之前的請求的uri的格式為:/webTest/filter/filter3.jsp

34              * 而getRequestDispatcher這種方法傳遞過去的是一個相對路徑,不需要再加上/webTest

35              * 這個方法可以把頁面表單的值傳遞到另外一個頁面,而不隻是純粹的跳轉

36 */

37             request.getRequestDispatcher(targetUri.substring(8)).forward(request, response);

38         }else{

39             response.sendRedirect("http://127.0.0.1:8088/webTest/filter1/filter2.jsp");

40         }

41     }

42 }

       login.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib prefix ="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>  

  <head>

    <base href="<%=basePath%>">

        <title>測試filter</title>

        <meta http-equiv="pragma" content="no-cache">

        <meta http-equiv="cache-control" content="no-cache">

        <meta http-equiv="expires" content="0">

        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    

        <meta http-equiv="description" content="This is my page">

        <!--    <link rel="stylesheet" type="text/css" href="styles.css">    -->  

   </head> 

<body>    

   <c:set var = "passed" value = "passing" scope = "session">

   </c:set>

    <form action = "filter/LoginCheck" method = "post">

        <table>

            <tr>

                <th>使用者賬号:</th>

                <td><input type = "text" name = "user" value = ""/></td>

            </tr>

                <th>登入密碼:</th>

                <td><input type = "password" name = "pwd" value = ""/></td>

                <th>

                    <input type = "hidden" name = "originalUri" value = "${requestScope.originalUri}"/>

                </th>

               <td><input type = "submit" name = "submit" value = "送出"/></td>           </tr>

        </table>

    </form>

  </body>

</html>

    filter2.jsp

1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 

2 <%@ taglib prefix ="c" uri ="http://java.sun.com/jsp/jstl/core"%> 

3 <% 

4 String path = request.getContextPath(); 

5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 

6 %> 

7  

8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 

9 <html>

10   <head>

11     <base href="<%=basePath%>">

12     

13     <title>My JSP 'filter2.jsp' starting page</title>

14     

15     <meta http-equiv="pragma" content="no-cache">

16     <meta http-equiv="cache-control" content="no-cache">

17     <meta http-equiv="expires" content="0">   

18     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

19     <meta http-equiv="description" content="This is my page">

20     <!--21     <link rel="stylesheet" type="text/css" href="styles.css">22 -->23 24   </head>25   26   <body>

27       HHHHH

28      

29   </body>

30 </html>

    filter3.jsp

1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

3 <%

4 String path = request.getContextPath();

5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

6 %>

8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

12    

13     <title>My JSP 'filter3.jsp' starting page</title>

14    

17     <meta http-equiv="expires" content="0">    

20     <!--21     <link rel="stylesheet" type="text/css" href="styles.css">

22 -->

23

24   </head>

26   <body>

27     <c:out value="${user}"></c:out> <br>

28     <c:out value="${pwd}"></c:out> <br>

      web.xml:  

1 <?xml version="1.0" encoding="UTF-8"?>

2 <web-app version="2.5"  

3     xmlns="http://java.sun.com/xml/ns/javaee"  

4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  

6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

7     <servlet>

8         <servlet-name>LoginCheck</servlet-name>

9         <servlet-class>filter.LoginCheck</servlet-class>

10     </servlet>

11     <servlet-mapping>

12         <servlet-name>LoginCheck</servlet-name>

13         <url-pattern>/filter/LoginCheck</url-pattern>

14     </servlet-mapping>

15    

16     <filter>

17         <filter-name>SessionCheck</filter-name>

18         <filter-class>filter.SessionCheck</filter-class>

19         <init-param>

20             <param-name>targetUri</param-name>

21             <param-value>/filter1/login.jsp</param-value>

22         </init-param>

23     </filter>

24     <filter-mapping>

25         <filter-name>SessionCheck</filter-name>

26         <url-pattern>/*</url-pattern>

27     </filter-mapping>

28   <welcome-file-list>

29     <welcome-file>index.jsp</welcome-file>

30   </welcome-file-list>

31 </web-app>

      代碼就是以上這些,效果:

  直接通路filter3.jsp,将會跳轉到login.jsp,當通過使用者認證之後就會跳轉到filter3.jsp,這個功能很好用,比如csdn下載下傳東西,你沒有登入直接點選下載下傳,系統會讓你先登入,登入完了可以直接進入到下載下傳頁面,不需要再進行其他的操作。

  直接通路login.jsp,通過認證以後會跳轉到預設的頁面,比如csdn,直接登入的話,會跳轉到csdn的首頁

  注意:此例子的使用者名和密碼分别為 LH123和123LH,隻有用這對組合才可以通過認證,才得以測試本例子。 

本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/735592,如需轉載請自行聯系原作者