filter的生命周期和servlet相似:init()->doFilter()->destroy(),主要用于对用户请求进行预处理,不能直接向用户生成响应。
一、下面看一个小例子:
1. xml的配置,主要配置filter的classpath和过滤的路径:
<filter> <filter-name>UserFilter</filter-name> <filter-class>JspServletJavaBean.UserFilter</filter-class> </filter> <filter-mapping> <filter-name>UserFilter</filter-name> <url-pattern>/jspservletjavabean/*</url-pattern> </filter-mapping>
2. UserFilter代码:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class UserFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)arg0; HttpServletResponse res=(HttpServletResponse)arg1; HttpSession session=req.getSession(); if(session.getAttribute("username")==null){ System.out.println("null~~"); res.sendRedirect("../temp/login.jsp"); }else{ arg2.doFilter(arg0,arg1); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
这个filter的作用就是对/jspservletjavabean/*下的请求进行过滤,根据session判断用户是否登陆。
二、多个filter和servlet之间的执行顺序
过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题。多个filter就组成了一个filter chain,filter过滤连的示意图如下:
关于访问的顺序:
filter1.java
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { // TODO Auto-generated method stub System.out.println("in filter 1."); arg2.doFilter(arg0, arg1); System.out.println("Getting out of filter 1"); }
filter2.java
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { // TODO Auto-generated method stub System.out.println("in filter 2."); arg2.doFilter(arg0, arg1); System.out.println("Getting out of filter 2"); }
servlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("hello the world...."); response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); response.setHeader("Location", "../show.jsp"); System.out.println("hello world is coming!!!!!!!!!"); }
xml的配置
<filter> <filter-name>Filter1</filter-name> <filter-class>Filter1</filter-class> </filter> <filter> <filter-name>Filter2</filter-name> <filter-class>Filter2</filter-class> </filter> <filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>Filter2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
访问这个Servlet,会看到控制台输出如下信息:
in simple filter 1.
in simple filter 2.
hello the world....
hello world is coming!!!!!!!!!
Getting out of simple filter 2
Getting out of simple filter 1 ---------@
in simple filter 1.
in simple filter 2.
Getting out of simple filter 2
Getting out of simple filter 1
分析:在@以上出现得说明了filter chain访问了Servlet,最后是Servlet输出内容,然后再回到filter chain的。
而@后面的就是Servlet转向的show.jsp页面。
总结:在doFilter()后的总在最后访问完才运行。而且对于Filter来说,顺序就像栈那样,FILO。