过滤器
过滤器的作用
对请求作统一处理(如编码格式,过滤无效数据,验证用户权限等)之后再执行servlet中的代码,而不用每次都在servlet中处理,这样大大减少了重复劳动的工作
原理
- 当用户访问服务器时,请求先被过滤器拦截下来(如果有过滤器的时候)
- 在过滤器里面进行处理(具体在doFilter()方法中)
在doFilter()方法里面调用chain.doFilter(request, response);如果有其他的过滤器就进入下一个过滤器如果没有,就进入用户访问的资源(servlet或者jsp等) - 执行完servlet里面的代码后还要返回到过滤器中(有多个过滤器时,逐个返回)
多个过滤器的执行顺序
1、如果是在xml中配置的过滤器
则按照xml中的先后执行
2、如果是通过注解@WebFilter(“/*”)的方式配置的过滤器
则按照字符串比较大小的方式将过滤器的类名进行比较,排序小的先执行
过滤器的生命周期
- 在服务器启动的时候构造过滤器对象并初始化
1、调用构造方法
2、调用init()方法 - 用户向服务器发来请求的时候执行doFilter()
3、调用doFilter()方法 - Reload项目或者关闭服务器的时候销毁所有的对象
4、调用destroy()
简单代码演示
@WebFilter("/*")
public class TestFilter_1 implements Filter{
/**
* 构造方法和初始化方法在服务器启动的时候就执行完毕
*/
public TestFilter_1() {
System.out.println("构造器");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("初始化方法");
}
/**
* 该方法是用户发来请求的时候执行
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("进入TestFilter_1");
//放行,如果还有过滤器就进入下一个过滤器
chain.doFilter(request, response);
System.out.println("执行完doFilter,回到TestFilter_1");
}
/**
* 服务器停止的时候销毁(重新加载的时候)
*/
@Override
public void destroy() {
System.out.println("销毁过滤器");
}
}
@WebFilter("/*")
public class TestFilter_2 implements Filter {
public TestFilter_2() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("进入HelloFilter2");
chain.doFilter(request, response);
System.out.println("执行完doFilter,回到TestFilter_2");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理开始请求");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
控制台打印结果
进入TestFilter_1
进入HelloFilter2
处理开始请求
执行完doFilter,回到TestFilter_2
执行完doFilter,回到TestFilter_1