首页 > 学院 > 开发设计 > 正文

JavaWeb——过滤器

2019-11-14 23:28:52
字体:
来源:转载
供稿:网友
javaWeb——过滤器过滤器简介

  WEB过滤器是一个服务器端组件,它可以截取用户端的请求与相应信息,并对这些信息过滤。

过滤器的工作原理和生命周期

  在没有Web过滤器的情况下,用户直接访问服务器上的Web资源。但是如果存在过滤器,用户就不可以直接访问过滤器了。

  Web容器启动的时候过滤器就已经启动了,用户的请求到达过滤器,过滤器判断用户的请求是否符合过滤规则,如果符合规则则将用户的请求发送给Web资源,Web资源将响应信息发送给过滤器,过滤器将Web资源的响应发送给用户。工作原理如下图所示:

  过滤器的生命周期:

  其中实例化方法在Web容器开始装载的时候就执行,初始化方法配置一些初始化参数,Web容器卸载(服务器关闭)的时候执行销毁方法。过滤方法会执行多次,其他方法只会执行一次。

第一个过滤器

    1.创建一个类实现javax.servlet.Filter接口。需要实现该接口中的3个方法。

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class FirstFilter implements Filter {13 14     public void destroy() {15         System.out.PRintln("*********执行过滤器的销毁方法*******");16 17     }18 19     public void doFilter(ServletRequest request, ServletResponse response,20             FilterChain filterChain) throws IOException, ServletException {21         System.out.println("*******开始执行过滤器的doFilter方法*********");22         filterChain.doFilter(request, response);23         System.out.println("*******结束执行过滤器的doFilter方法**********");24     }25 26     public void init(FilterConfig arg0) throws ServletException {27         System.out.println("*******执行过滤器的初始化方法***********");28 29     }30 31 }
FirstFilter.java
  • init(FilterConfig):过滤器的初始化方法,Web容器创建过滤器之后将调用这个方法,在这个方法中可以读取web.xml中的过滤器参数。
  • doFilter(ServletRequest,ServletResponse,FilterChain):完成实际的过滤操作,是过滤器的核心方法。当用户请求访问与过滤器相关联的URL的时候,Web容器将先调用过滤器的doFilter方法。FilterChain参数可以调用chain.doFilter方法【放行方法】,将请求传送给下一个过滤器(或者目标资源),或利用转发、重定向将请求转发给其他资源。
  • destroy():Web容器在销毁过滤器实例前调用该方法,在这个方法中可以释放过滤器占用的资源。【大多数情况下用不到】

    2.在web.xml中配置过滤器(和再web.xml中注册servlet类似)

  在MyEclipse中提供了可视化的配置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   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12       <!-- 配置过滤器开始 -->13     <filter>14         <filter-name>FirstFilter</filter-name>15         <filter-class>filter.FirstFilter</filter-class>16     </filter>17     <filter-mapping>18         <filter-name>FirstFilter</filter-name>19         <url-pattern>/*</url-pattern>20     </filter-mapping>21     <!-- 配置过滤器结束 -->22     23 </web-app>
web.xml

  在index.jsp中我们在控制台打印一行信息:"**********这是index.jsp*********";  

  将项目部署到服务器,启动服务器:

  在Servlet容器装载的时候,执行过滤器的init方法,当用户请求页面的时候首先执行doFilter()方法,当Servlet容器卸载的时候执行过滤器的销毁方法。【注意:用户的请求先是到达过滤器并不是直接访问的Web资源】

  还有一点需要注意:用户虽然能够改变用户请求的资源(例如:网上购物的时候点击“立即购买”,这个请求先要到达过滤器,如果过滤器检测到用户没有登录,就会将页面重定向到登陆页),但是过滤器不能直接处理用户的请求(过滤器不是Servlet),不能直接返回数据。

过滤器链

  针对同一个用户请求(url-pattern),与之匹配的过滤器有多个,这个时候用户请求就会依次通过各个过滤器到达web资源。

  新建2个过滤器:

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class FirstFilter implements Filter {13 14     public void destroy() {15         System.out.println("*********过滤器1----->销毁方法*******");16 17     }18 19     public void doFilter(ServletRequest request, ServletResponse response,20             FilterChain filterChain) throws IOException, ServletException {21         System.out.println("*******开始执行过滤器1----->doFilter方法*********");22         filterChain.doFilter(request, response);23         System.out.println("*******结束执行过滤器1----->doFilter方法**********");24     }25 26     public void init(FilterConfig arg0) throws ServletException {27         System.out.println("*******执行过滤器1------>初始化方法***********");28 29     }30 31 }
FirstFilter.java
 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class SecondFilter implements Filter {13 14     public void destroy() {15         System.out.println("*********过滤器2----->销毁方法*******");16     }17 18     public void doFilter(ServletRequest request, ServletResponse response,19             FilterChain filterChain) throws IOException, ServletException {20         System.out.println("*******开始执行过滤器2----->doFilter方法*********");21         filterChain.doFilter(request, response);22         System.out.println("*******结束执行过滤器2----->doFilter方法**********");23     }24 25     public void init(FilterConfig arg0) throws ServletException {26         System.out.println("*******执行过滤器2------>初始化方法***********");27     }28 29 }
SecondFilter.java

  在web.xml中配置两个过滤器(第一个过滤器在前面,两个过滤器都匹配index.jsp)

 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   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12       <!-- 配置过滤器开始 -->13       <!-- 过滤器1 -->14     <filter>15         <filter-name>FirstFilter</filter-name>16         <filter-class>filter.FirstFilter</filter-class>17     </filter>18     <filter-mapping>19         <filter-name>FirstFilter</filter-name>20         <url-pattern>/index.jsp</url-pattern>21     </filter-mapping>22     <!-- 过滤器2 -->    23     <filter>24         <filter-name>SecondFilter</filter-name>25         <filter-class>filter.SecondFilter</filter-class>26     </filter>27     <filter-mapping>28         <filter-name>SecondFilter</filter-name>29         <url-pattern>/index.jsp</url-pattern>30     </filter-mapping>31    <!-- 配置过滤器结束 -->32     33 </web-app>
web.xml

  在index.jsp中我们打印如下的一句话:System.out.println("******** 这是index.jsp,处理过程完成 *********");

运行结果:

过滤器的分类:

  Servlet 2.5中将过滤器分为4种,如下图所示:

1.REQUEST过滤器

  新建一个过滤器FirstFilter(在web.xml中配置两个过滤地址index.jsp和main.jsp): 

 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   <display-name></display-name>     8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11   12       <!-- 配置过滤器开始 -->13     <filter>14         <filter-name>FirstFilter</filter-name>15         <filter-class>filter.FirstFilter</filter-class>16     </filter>17     <filter-mapping>18         <filter-name>FirstFilter</filter-name>19         <url-pattern>/index.jsp</url-pattern>20         <dispatcher>REQUEST</dispatcher>21     </filter-mapping>22     <filter-mapping>23         <filter-name>FirstFilter</filter-name>24         <url-pattern>/main.jsp</url-pattern>25         <dispatcher>REQUEST</dispatcher>26     </filter-mapping>27    <!-- 配置过滤器结束 -->28     29 </web-app>
web.xml

  在FirstFilter的doFilter方法中将页面重定向到main.jsp

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 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 14 public class FirstFilter implements Filter {15 16     public void destroy() {17         System.out.println("*********过滤器1----->销毁方法*******");18 19     }20 21     public void doFilter(ServletRequest request, ServletResponse response,22             FilterChain filterChain) throws IOException, ServletException {23         24         HttpServletRequest req = (HttpServletRequest) request;25         HttpServletResponse res = (HttpServletResponse) response;26         27         System.out.println("*******开始执行过滤器1----->doFilter方法*********");28         res.sendRedirect(req.getContextPath() + "/main.jsp");//重定向29         System.out.println("*******结束执行过滤器1----->doFilter方法**********");30     }31 32     public void init(FilterConfig arg0) throws ServletException {33         System.out.println("*******执行过滤器1------>初始化方法***********");34 35     }36 37 }
FirstFilter.java

  启动服务器:

  当我们访问index.jsp的时候,过滤器将页面重定向到main.jsp——相当于我们又重新请求了main.jsp,main.jsp又会遇到过滤器,如此页面不停重定向到main.jsp,产生了死循环不会输出任何内容!

  换一种方式,我们在过滤器中使用服务器内部转发的方式将页面转发到main.jsp(main.jsp向页面打印"这是main.jsp")。

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 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 14 public class FirstFilter implements Filter {15 16   public void destroy() {17     System.out.println("*********过滤器1----->销毁方法*******");18 19   }20 21   public void doFilter(ServletRequest request, ServletResponse response,22       FilterChain filterChain) throws IOException, ServletException {23     24     HttpServletRequest req = (HttpServletRequest) request;25     HttpServletResponse res = (HttpServletResponse) response;26     27     System.out.println("*******开始执行过滤器1----->doFilter方法*********");28     req.getRequestDispatcher("main.jsp").forward(request, response);//使用服务器内部转发29     System.out.println("*******结束执行过滤器1----->doFilter方法**********");30   }31 32   public void init(FilterConfig arg0) throws ServletException {33     System.out.println("*******执行过滤器1------>初始化方法***********");34 35   }36 37 }
FirstFilter.java

  运行结果:

2.FORWARD过滤器

  将main.jsp的过滤规则改为FORWARD。

1 …… 2 <filter-mapping>3         <filter-name>FirstFilter</filter-name>4         <url-pattern>/main.jsp</url-pattern>5         <dispatcher>FORWARD</dispatcher>6  </filter-mapping>7 ……

  重新访问index.jsp

3.INCLUDE过滤器

  INCLUDE和FORWARD过滤器的使用类似,对应的jsp动作是include。

4.ERROR过滤器

  例如我们访问一个错误的页面时,系统会给出一个错误,用户看不懂这个错误是什么概念——我们需要给出一些人性化的提示。

  以下是没有在web.xml中配置错误页,用户访问一个不存在的页面:

  在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   <display-name></display-name>  8   <welcome-file-list> 9     <welcome-file>index.jsp</welcome-file>10   </welcome-file-list>11 12   <!-- 配置错误页面 -->13   <error-page>14     <error-code>404</error-code>15     <location>/error.jsp</location>16   </error-page>17 18 </web-app>
web.xml

  在web.xml中配置404错误的页面为error.jsp则当用户访问一个不存在的页面时将会将error.jsp中的内容输出(以人性化的方式提示用户):

  当页面出现错误或者异常的时候,ERROR过滤器可以将错误或者异常捕捉到,系统会记录下错误的信息,程序员就可以查找错误的来源。

  新建一个ErrorFilter,并在web.xml中进行如下配置:

 1 <!-- 配置错误页面 --> 2   <error-page> 3     <error-code>404</error-code> 4     <location>/error.jsp</location> 5   </error-page> 6 …… 7 <filter> 8     <filter-name>ErrorFilter</filter-name> 9     <filter-class>filter.ErrorFilter</filter-class>10 </filter>11 <filter-mapping>12     <filter-name>ErrorFilter</filter-name>13     <url-pattern>/error.jsp</url-pattern>14     <dispatcher>ERROR</dispatcher>15 </filter-mapping>16 ……
web.xml

  错误过滤器ErrorFilter

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 public class ErrorFilter implements Filter {13 14     public void destroy() {15 16     }17 18     public void doFilter(ServletRequest request, ServletResponse response,19             FilterChain filterChain) throws IOException, ServletException {20         System.out.println("检测到错误信息!");21         filterChain.doFilter(request, response);//注意打印错误后要放行,不然页面不会显示22     }23 24     public void init(FilterConfig filterConfig) throws ServletException {25 26     }27 28 }
ErrorFilter.java

  

  J2EE5默认的web.xml是Servlet 2.5,J2EE6默认的web.xml是Servlet 3.0【支持异步处理】。

  异步处理:如果在过滤器的doFilter()方法中页面跳转到了一个Servlet用于业务的处理,加入Servlet处理的业务时间花费很多,这时过滤器就会一直等待Servlet执行完成。这样用户体验就会非常差。Servlet 3.0支持异步处理。

  在Servlet中新加入了@WebFilter Annotation。该Annotation用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置相应的类,将响应的类部署为过滤器。——因此我们不需要在web.xml中配置过滤器,只需要用注解的方式。@WebFilter的常用属性如下:

  下面使用J2EE6.0创建一个Web项目,创建一个过滤器名称为AsyncFilter,使用@WebFilter Annotation配置该过滤器(PS:可以不再web.xml中注册该过滤器):

 1 package filter; 2  3 import java.io.IOException; 4  5 import javax.servlet.DispatcherType; 6 import javax.servlet.Filter; 7 import javax.servlet.FilterChain; 8 import javax.servlet.FilterConfig; 9 import javax.servlet.ServletException;10 import javax.servlet.ServletRequest;11 import javax.servlet.ServletResponse;12 import javax.servlet.annotation.WebFilter;13 14 @WebFilter(filterName = "AsyncFilter", value = { "/servlet/AsyncServlet" }, asyncSupported = true, dispatcherTypes = {15         DispatcherType.ASYNC, DispatcherType.REQUEST })16 public class AsyncFilter implements Filter {17 18     @Override19     public void destroy() {20         System.out.println("***** 销毁AsyncFilter *****");21     }22 23     @Override24     public void doFilter(ServletRequest request, ServletResponse response,25             FilterChain filterChain) throws IOException, ServletException {26         System.out.println("***** 开始AsyncFilter *****");27         filterChain.doFilter(request, response);//放行28         System.out.println("***** 结束AsyncFilter *****");29     }30 31     @Override32     public void init(FilterConfig filterConfig) throws ServletException {33         System.out.println("***** 初始化AsyncFilter *****");34     }35 36 }
AsyncFilter.java

  创建一个处理业务的Servlet(该Servlet在doGet方法中使用了线程的休眠方法休眠了10s模拟业务的花费时间)

 1 package servlet; 2  3 import java.io.IOException; 4 import java.util.Date; 5  6 import javax.servlet.AsyncContext; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 12 public class AsyncServlet extends HttpServlet {13     14     public class Excutor implements Runnable{15         private AsyncContext context;16         public Excutor(AsyncContext context) {17             this.context = context;18         }19 20         @Override21         public void run() {22             // 执行相关的复杂业务23             try {24                 Thread.sleep(1000*10);//休眠10s25 //                context.getRequest();26 //                context.getResponse();27                 System.out.println("业务完成执行时间:"+new Date());28             } catch (InterruptedException e) {29                 e.printStackTrace();30             }31         }32         33     }34 35     public AsyncServlet() {36         super();37     }38 39     public void destroy() {40         super.destroy(); // Just puts "destroy" string in log41     }42 43     public void doGet(HttpServletRequest request, HttpServletResponse response)44             throws ServletException, IOException {45         46         AsyncContext context = request.startAsync(); //HttpServletRequest对象开始异步方法47 //        context.getRequest();48 //        context.getResponse();49         50         System.out.println("Servlet执行开始时间:"+new Date());51         new Thread(new Excutor(context)).start();52         request.getRequestDispatcher("/index.jsp").forward(request, response);53         System.out.println("Servlet执行结束时间:"+new Date());54     }55 56     public void doPost(HttpServletRequest request, HttpServletResponse response)57             throws ServletException, IOException {58 59         doGet(request, response);60     }61 62     public void init() throws ServletException {63 64     }65 66 }
AsyncServlet.java

  编写好异步处理业务的Servlet类之后一定要在web.xml中配置该Servlet启用异步,如下图所示:

  在index.jsp中有一个链接指向AsyncServlet:

<a href="<%=request.getContextPath() %>/servlet/AsyncServlet">点击跳转到AsyncServlet处理业务</a>

  运行结果:

过滤器在实际项目中的应用场景

用户身份的验证

  例如现在有一个web项目,登陆页login.jsp将用户名和密码提交给LoginServlet处理,Servlet使用request.getParameter方法获得表单中的用户名和密码,将用户名和密码进行验证,验证成功则页面重定向到success.jsp,显示登陆成功和登录的用户名【保存在session中再从session中取出】;如果登录失败则重定向到failure.jsp。

  在不使用过滤器的情况下,即使用户不进行登录也可以访问到success.jsp——任何人都可以访问到success.jsp,这显然来说不安全。

  验证用户身份的Servlet(验证用户名和密码都是admin):

 1 package servlet; 2  3 import java.io.IOException; 4  5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import javax.servlet.http.HttpSession;10 11 public class LoginServlet extends HttpServlet {12 13     public LoginServlet() {14         super();15     }16 17     public void destroy() {18         super.destroy(); // Just puts "destroy" string in log19     }20 21     public void doPost(HttpServletRequest request, HttpServletResponse response)22             throws ServletException, IOException {23         String username = request.getParameter("username");24         String passWord = request.getParameter("password");25         26         if ("admin".equals(username)&&"admin".equals(password)) {27             // 验证通过28             HttpSession session = request.getSession();29             session.setAttribute("username", username);//把用户名放入session中30             response.sendRedirect(request.getContextPath()+"/success.jsp");31         }else {32             // 验证失败33             response.sendRedirect(request.getContextPath()+"/failure.jsp");34         }35     }36 37     public void init() throws ServletException {38 39     }40 41 }
LoginServlet.java

如下图所示:

  现在我们要做这样一件事:只有用户登录成功才可以访问到success.jsp,反之跳转到登录界面。即:不允许未登录用户访问success.jsp。

  创建一个登录校验的过滤器LoginFilter并在web.xml中配置该过滤器的url为success.jsp

 1 package servlet; 2  3 import java.io.IOException; 4  5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import javax.servlet.http.HttpSession;10 11 public class LoginServlet extends HttpServlet {12 13     public LoginServlet() {14         super();15     }16 17     public void destroy() {18         super.destroy(); // Just puts "destroy" string in log19     }20 21     public void doPost(HttpServletRequest request, HttpServletResponse response)22             throws ServletException, IOException {23         String username = request.getParameter("username");24         String password = request.getParameter("password");25         26         if ("admin".equals(username)&&"admin".equals(password)) {27             // 验证通过28             HttpSession session = request.getSession();29             session.setAttribute("username", username);//把用户名放入session中30             response.sendRedirect(request.getContextPath()+"/success.jsp");31         }else {32             // 验证失败33             response.sendRedirect(request.getContextPath()+"/failure.jsp");34         }35     }36 37     public void init() throws ServletException {38 39     }40 41 }
LoginFilter.java
 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   <display-name></display-name> 8   <servlet> 9     <description>This is the description of my J2EE component</description>10     <display-name>This is the display name of my J2EE component</display-name>11     <servlet-name>LoginServlet</servlet-name>12     <servlet-class>servlet.LoginServlet</servlet-class>13   </servlet>14 15   <servlet-mapping>16     <servlet-name>LoginServlet</servlet-name>17     <url-pattern>/servlet/LoginServlet</url-pattern>18   </servlet-mapping>    19   <welcome-file-list>20     <welcome-file>index.jsp</welcome-file>21   </welcome-file-list>22     <filter>23         <filter-name>LoginFilter</filter-name>24         <filter-class>filter.LoginFilter</filter-class>25     </filter>26     <filter-mapping>27         <filter-name>LoginFilter</filter-name>28         <url-pattern>/success.jsp</url-pattern>29     </filter-mapping>30 </web-app>
web.xml

  加入过滤器之后(只有成功登录的用户【session中保存了该用户的用户名】才可以访问index.jsp):

 在实际的开发中一个网站的页面成百上千,这时我们可以使用通配符"/*"来匹配所有的url。但是这样带来一个问题:

 当我们新建立一个session的时候,访问任何页面都会被重定向到login.jsp,login.jsp自己也重定向到login.jsp,这样就形成了重定向循环

  这时就需要在过滤器中判断页面是否是login.jsp,如果是login.jsp或者请求的是LoginServlet就直接放行。在LoginFilter的doFilter方法中添加这样几行代码:

1 if (req.getRequestURI().indexOf("login.jsp")!=-1||req.getRequestURI().indexOf("LoginServlet")!=-1) {2     filterChain.doFilter(request, response); // 如果用户请求的是login.jsp直接放行3     return; // 这一行代码一定要加上啊!4 }

  运行结果:

  上述程序看似已经没有问题,但是还存在一个小bug,当我们在登陆页输入一个错误的用户名和密码页面并不会重定向到failure.jsp而是重定向到了login.jsp。如下图所示:

  这是因为虽然我们在Servlet验证失败的时候将页面重定向到了failure.jsp,failure.jsp又被过滤器重定向到了login.jsp【因为过滤规则为所有的页面,并且session中没有用户名】

  这时我们就会发现我们在doFilter中需要例外的页面越来越多(登陆页面、成功页面、失败页面、错误页面……)。为了减轻工作的复杂度,我们可以使用过滤器的init方法中的FilterConfig对象。

 1. 在web.xml中配置不过滤页面的初始化参数:

  2.  在过滤方法中使用以上初始化参数。

 1 public class LoginFilter implements Filter{ 2  3     private FilterConfig filterConfig;// 声明一个FilterConfig对象 4  5     public void init(FilterConfig filterConfig) throws ServletException { 6         this.filterConfig = filterConfig; // 初始化方法的时候给filterConfig赋值 7     } 8      9     public void destroy() {10         11     }12 13     public void doFilter(ServletRequest request, ServletResponse response,14             FilterChain filterChain) throws IOException, ServletException {15         // 代码省略16     }17 18 }

  3. 在doFilter方法中使用FilterConfig对象获得初始化参数。

 1 public void doFilter(ServletRequest request, ServletResponse response, 2         FilterChain filterChain) throws IOException, ServletException { 3     HttpServletRequest req = (HttpServletRequest) request; 4     HttpServletResponse res = (HttpSer
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表