jsp之过滤器
简单介绍下servlet的过滤器,虽然标题是Jsp
1.创建一个过滤器
我们首先创建一个web工程,
工程首页有一个连接
<a href="<%=path %>/servlet/loginServlet?username=管理员&password=1">进入后台</a>
这里,我们创建一个servlet(关于如何创建和访问servlet不是我们今天的重点)
1 @Override 2 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 3 throws ServletException, IOException { 4 5 String username = req.getParameter("username"); 6 String password = req.getParameter("password"); 7 8 }
这里我们发现username会是乱码,因此我们需要手动为其设置编码
req.setCharacterEncoding("GBK");
这个没有问题,但是假设有N个servlet或则说有许多不同逻辑的请求,自然就需要很多的同样操作
因此就需要一个字符的过滤器
OK
要实现过滤器,必须实现javax.servlet.Filter接口
并重写doFilter方法
先贴代码 在解释
1 /** 2 * 字符过滤器 3 * 4 */ 5 // 实现过滤器的方法 实现filter接口 重写doFilter方法 6 public class EncodeFilter implements Filter { 7 8 private String encode = null; 9 private boolean ignore = false;// 过滤器开关 10 11 public void destroy() { 12 encode = null; 13 ignore = false; 14 } 15 16 public void doFilter(ServletRequest request, ServletResponse response, 17 FilterChain chain) throws IOException, ServletException { 18 if (!ignore) { 19 if (null == request.getCharacterEncoding()) { 20 request.setCharacterEncoding(encode); 21 22 } 23 } 24 chain.doFilter(request, response); 25 26 } 27 28 public void init(FilterConfig filterConfig) throws ServletException { 29 String encode = filterConfig.getInitParameter("encode"); 30 String ignore = filterConfig.getInitParameter("ignore"); 31 if (this.encode == null) 32 this.encode = encode; 33 if ("1".equals(ignore) || "yes".equals(ignore)) { 34 this.ignore = true; 35 } 36 } 37 38 }
1 <filter> 2 <filter-name>encodeFilter</filter-name> 3 <filter-class>com.lwx.filter.EncodeFilter</filter-class> 4 <init-param> 5 <param-name>encode</param-name> 6 <param-value>GBK</param-value> 7 </init-param> 8 <init-param> 9 <param-name>ignore</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 </filter> 13 <filter-mapping> 14 <filter-name>encodeFilter</filter-name> 15 <url-pattern>/*</url-pattern> 16 </filter-mapping>
这里解释下
<filter-mapping>中的<url-pattern>就是过滤器要过滤的对象/* 就是对所有的请求进行过滤
当然这里还有一个过滤器的开关ignore 当ignore为true/1/yes的时候,则过滤器不起作用,还有一个就是过滤器要设置的编码格式的值
java代码中,
init方法是初始化过滤器的时候调用一次
destroy 则不用解释了
doFilter 则是需要我们去重写的
OK 到此一个完整的字符过滤器就算结束,但是我们的话题还没有结束
现在我有一个想法,那就是对非法用户(没有登录的用户和没有权限访问的用户)进行过滤
二、登录过滤器
我们知道,很多时候我们在影响用户请求的时候,都需要判断用户是否已经登录,或则他的session是否已经失效,如果是的话,则跳到登录页,等待重新登录后才可以继续下一步的操作
OK
假设现在我们有一个登录的页面
代码如下
1 <form action="<%=path %>/servlet/loginServlet?task=login" method="post"> 2 <div>用户名:<input type="text" name="username"></div> 3 <div>密码:<input type="password" name="password"></div> 4 <div><input type="submit" value="登录"></div> 5 </form>
if (task.equals("login")) { if (null != username && username.trim().length() > 0 && username.equals("lwx")) { if (null != password && password.trim().length() > 0 && password.equals("1")) { User user = new User(); user.setUsername(username); req.getSession().setAttribute("user", user); resp.sendRedirect(req.getContextPath() + "/manager/"); } } }
后台的处理代码
当用户名等于lwx并且密码为1的时候,我们将跳转到/manager/index.jsp
假设现在用户知道了这个地址,就可以轻松的访问我们的页面了,因此在进去之前需要做过滤
同时/servlet/loginServlet?task=login 这个请求又是不需要过滤的
因此综上考虑 ,我们这样设计过滤器
1 public class LoginFilter implements Filter{ 2 String permitUrls[]=null; 3 boolean ignore=false; 4 String gotoUrl=null; 5 6 public void destroy() { 7 permitUrls=null; 8 ignore=false; 9 gotoUrl=null; 10 11 } 12 13 public void doFilter(ServletRequest request, ServletResponse response, 14 FilterChain chain) throws IOException, ServletException { 15 HttpServletRequest res=(HttpServletRequest) request; 16 HttpServletResponse resp=(HttpServletResponse)response; 17 System.out.println("登录过滤器"); 18 if(!ignore){ 19 if(!isPermitUrl(request)){ 20 if(filterCurrUrl(request)){ 21 resp.sendRedirect(res.getContextPath()+gotoUrl); 22 return ; 23 } 24 } 25 26 27 } 28 chain.doFilter(request, response); 29 } 30 31 public boolean isPermitUrl(ServletRequest request){ 32 boolean isPermit=false; 33 34 if(permitUrls!=null&&permitUrls.length>0){ 35 for (int i = 0; i < permitUrls.length; i++) { 36 if(permitUrls[i].equals(currentUrl(request))){ 37 isPermit=true; 38 break; 39 } 40 } 41 } 42 return isPermit; 43 } 44 45 public boolean filterCurrUrl(ServletRequest request){ 46 47 boolean filter=false; 48 HttpServletRequest res=(HttpServletRequest) request; 49 User user =(User) res.getSession().getAttribute("user"); 50 if(null==user) 51 filter=true; 52 53 return filter; 54 55 } 56 57 //xx.jsp 58 // servlet/aaServlet?task=11&bb=yy 59 60 public String currentUrl(ServletRequest request){ 61 62 HttpServletRequest res=(HttpServletRequest) request; 63 String task=request.getParameter("task"); 64 String path=res.getContextPath(); 65 String uri=res.getRequestURI(); 66 if(task!=null){//uri格式 xx/ser 67 uri=uri.substring(path.length(), uri.length())+"?"+"task="+task; 68 }else{ 69 uri=uri.substring(path.length(), uri.length()); 70 } 71 System.out.println("当前请求地址:"+uri); 72 return uri; 73 } 74 75 76 public void init(FilterConfig filterConfig) throws ServletException { 77 String ignore =filterConfig.getInitParameter("ignore"); 78 String permitUrls =filterConfig.getInitParameter("permitUrls"); 79 String gotoUrl =filterConfig.getInitParameter("gotoUrl"); 80 81 if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) { 82 this.ignore = true; 83 } 84 if(permitUrls!=null&&permitUrls.length()>0); 85 this.permitUrls=permitUrls.split(","); 86 87 this.gotoUrl=gotoUrl; 88 } 89 90 91 92 }
1 <filter> 2 <filter-name>loginFilter</filter-name> 3 <filter-class>com.lwx.filter.LoginFilter</filter-class> 4 5 <init-param> 6 <param-name>ignore</param-name> 7 <param-value>false</param-value> 8 </init-param> 9 <init-param> 10 <param-name>permitUrls</param-name> 11 <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value> 12 </init-param> 13 <init-param> 14 <param-name>gotoUrl</param-name> 15 <param-value>/login/login.jsp</param-value> 16 </init-param> 17 </filter> 18 <filter-mapping> 19 <filter-name>loginFilter</filter-name> 20 <url-pattern>/*</url-pattern> 21 </filter-mapping>
1 public class User { 2 3 private String username; 4 private String password; 5 6 }
OK,登录过滤器仍然全部的请求地址,
permitUrls 用来告诉过滤器哪些请求是登录过滤器不需要过滤的,最简单的肯定是首页,和登录校验的地址
gotoUrl 表示当过滤器接收到非法请求的时候,需要跳转的页面 这样的好处是假设下次需要修改跳转的页面 只要修改配置文件,而不需要重新编译代码
三、权限过滤器
感觉到这里,视乎是可以告一个段落了,其实不然。
假设我们有一个一般的用户,他登录后请求的一个地址是管理员才可以访问的 那对于网站来说是非常不利的。因此权限的过滤器也是非常有必要的
还是先上代码
1 public class AuthorityFilter implements Filter{ 2 String permitUrls[]=null; 3 boolean ignore=false; 4 String gotoUrl=null; 5 6 public void destroy() { 7 permitUrls=null; 8 ignore=false; 9 gotoUrl=null; 10 11 } 12 13 public void doFilter(ServletRequest request, ServletResponse response, 14 FilterChain chain) throws IOException, ServletException { 15 HttpServletRequest res=(HttpServletRequest) request; 16 HttpServletResponse resp=(HttpServletResponse)response; 17 System.out.println("权限过滤器"); 18 if(!ignore){ 19 if(!isPermitUrl(request)){ 20 if(filterCurrUrl(request)){ 21 22 resp.sendRedirect(res.getContextPath()+gotoUrl); 23 return ; 24 } 25 } 26 27 28 } 29 chain.doFilter(request, response); 30 } 31 32 public boolean isPermitUrl(ServletRequest request){ 33 boolean isPermit=false; 34 35 if(permitUrls!=null&&permitUrls.length>0){ 36 for (int i = 0; i < permitUrls.length; i++) { 37 if(permitUrls[i].equals(currentUrl(request))){ 38 isPermit=true; 39 break; 40 } 41 } 42 } 43 return isPermit; 44 } 45 46 public boolean filterCurrUrl(ServletRequest request){ 47 48 boolean filter=true; 49 HttpServletRequest res=(HttpServletRequest) request; 50 User user =(User) res.getSession().getAttribute("user"); 51 //List authorities=user.getUserAuthorities(); 52 //遍历authorities判断是否是该用户拥有的权限 否则 53 //这里我们假定用户用户访问/manager/user_list.jsp的权限 54 String currentUrl=currentUrl( request); 55 if("/servlet/loginServlet?task=userlist".equals(currentUrl)) 56 filter=false; 57 58 59 60 61 return filter; 62 63 } 64 65 //xx.jsp 66 // servlet/aaServlet?task=11&bb=yy 67 68 public String currentUrl(ServletRequest request){ 69 70 HttpServletRequest res=(HttpServletRequest) request; 71 String task=request.getParameter("task"); 72 String path=res.getContextPath(); 73 String uri=res.getRequestURI(); 74 if(task!=null){//uri格式 xx/ser 75 uri=uri.substring(path.length(), uri.length())+"?"+"task="+task; 76 }else{ 77 uri=uri.substring(path.length(), uri.length()); 78 } 79 System.out.println("当前请求地址:"+uri); 80 return uri; 81 } 82 83 84 public void init(FilterConfig filterConfig) throws ServletException { 85 String ignore =filterConfig.getInitParameter("ignore"); 86 String permitUrls =filterConfig.getInitParameter("permitUrls"); 87 String gotoUrl =filterConfig.getInitParameter("gotoUrl"); 88 89 if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) { 90 this.ignore = true; 91 } 92 if(permitUrls!=null&&permitUrls.length()>0); 93 this.permitUrls=permitUrls.split(","); 94 95 this.gotoUrl=gotoUrl; 96 } 97 98 99 }
1 <filter> 2 <filter-name>encodeFilter</filter-name> 3 <filter-class>com.lwx.filter.EncodeFilter</filter-class> 4 <init-param> 5 <param-name>encode</param-name> 6 <param-value>GBK</param-value> 7 </init-param> 8 <init-param> 9 <param-name>ignore</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 </filter> 13 <filter> 14 <filter-name>authorityFilter</filter-name> 15 <filter-class>com.lwx.filter.AuthorityFilter</filter-class> 16 17 <init-param> 18 <param-name>ignore</param-name> 19 <param-value>false</param-value> 20 </init-param> 21 <init-param> 22 <param-name>permitUrls</param-name> 23 <!-- 事实上 权限过滤器时将是否已登录的功能剥离出来 为了说明区别特意加了一个/manager/public.jsp--> 24 <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp,/manager/,/manager/public.jsp,/error/noAuthority.jsp,/manager/user_list.jsp</param-value> 25 </init-param> 26 <init-param> 27 <param-name>gotoUrl</param-name> 28 <param-value>/error/noAuthority.jsp</param-value> 29 </init-param> 30 </filter> 31 <filter> 32 <filter-name>loginFilter</filter-name> 33 <filter-class>com.lwx.filter.LoginFilter</filter-class> 34 35 <init-param> 36 <param-name>ignore</param-name> 37 <param-value>false</param-value> 38 </init-param> 39 <init-param> 40 <param-name>permitUrls</param-name> 41 <param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value> 42 </init-param> 43 <init-param> 44 <param-name>gotoUrl</param-name> 45 <param-value>/login/login.jsp</param-value> 46 </init-param> 47 </filter> 48 <filter-mapping> 49 <filter-name>encodeFilter</filter-name> 50 <url-pattern>/*</url-pattern> 51 </filter-mapping> 52 <filter-mapping> 53 <filter-name>loginFilter</filter-name> 54 <url-pattern>/*</url-pattern> 55 </filter-mapping> 56 <filter-mapping> 57 <filter-name>authorityFilter</filter-name> 58 <url-pattern>/*</url-pattern> 59 </filter-mapping> 60
这里之所以把三个过滤器的配置都贴出来,及时说明下过滤器的顺序跟
<filter-mapping>在web.xml中的顺序有关
http://www.cnblogs.com/draem0507/archive/2012/11/09/2762613.html