现在web程序很多都用到统一认证这东西,刚好看《jsp2.0技术手册》看到这块,看完感觉有点模糊,所以就自己写代码试了一下,花了好长一段时间,原因终于在今天找到了,并且成功解决,但是我并没有因此而感到自豪,因为我越来越感觉自己蠢了,蠢得无可救药。废话不说了,看下面的东西吧:
用filter实现统一认证我用了5个页面,分别为:login.jsp,filter2.jsp,filter3.jsp,LoginCheck.java,SessionCheck.java.其中最主要的是SessionCheck.java.另外还需要配置web.xml文件,这个千万不能忘记哦。
下面是我的web程序的结构图:
下面看下各个页面的代码(内含很多注释,方便理解):
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 }
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;
9
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 }
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;
9
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 >
< tr >
< th > 登录密码: </ th >
< td >< input type = "password" name = "pwd" value = "" /></ td >
</ tr >
< th >
< input type = "hidden" name = "originalUri" value = "${requestScope.originalUri}" />
</ th >
< tr >
< td >< input type = "submit" name = "submit" value = "提交" /></ td > </ tr >
</ table >
</ form >
</ body >
</ html >
<% @ 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 >
< tr >
< th > 登录密码: </ th >
< td >< input type = "password" name = "pwd" value = "" /></ td >
</ tr >
< th >
< input type = "hidden" name = "originalUri" value = "${requestScope.originalUri}" />
</ th >
< tr >
< 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 >
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
%
>
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 'filter3.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
<
c:out
value
="${user}"
></
c:out
>
<
br
>
28
<
c:out
value
="${pwd}"
></
c:out
>
<
br
>
29
</
body
>
30
</
html
>
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,如需转载请自行联系原作者