过滤器与拦截器的区别

过滤器

过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。

作用

请求和响应的过滤,传入的 request,response 提前过滤掉一些信息,或者提前设置一些参数,然后再传入 servlet 或者 struts 的 action 进行业务逻辑,比如过滤掉非法 url(不是 login.jsp 的地址请求,如果用户没有登录都过滤掉),或者在传入 servlet 或 struts 的 action 前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话)。

Servlet过滤器的基本原理

在请求进入容器之后,还未进入 Servlet 之前进行预处理;在请求结束返回给前端之前进行后期处理。处理完成后,它会交给下一个过滤器处理,直到发送到目标为止。

拦截器

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。比如日志,安全等。

拦截器链,就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

一般拦截器方法都是通过动态代理的方式实现的。

作用

比如通过它来进行权限管理,或者判断用户是否登录,或者是像 12306 判断当前时间是不是购票时间。

区别

①拦截器是基于动态代理的,而过滤器是基于函数回调。
②拦截器不依赖于servlet容器,是通过动态代理实现,过滤器依赖于servlet容器。
③拦截器可以在方法前后,异常前后等调用,而过滤器只能在请求前和请求后各调用一次。
④拦截器可以利用依赖注入,因此在Spring框架程序中,优先拦截器。

1、过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	System.out.println("before...");
	chain.doFilter(request, response);
	System.out.println("after...");
}

2、拦截器是被包裹在过滤器之中的。

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	System.out.println("preHandle");
	return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
	System.out.println("postHandle");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
	System.out.println("afterCompletion");
}

执行顺序如下图

上面几个方法的执行顺序如下图:


本文永久更新地址:https://github.com/nnngu/LearningNotes/blob/master/_posts/2018-03-20-%E8%BF%87%E6%BB%A4%E5%99%A8%E4%B8%8E%E6%8B%A6%E6%88%AA%E5%99%A8%E7%9A%84%E5%8C%BA%E5%88%AB.md