拦截器和过滤器的执行顺序和区别
内容引用https://www.cnblogs.com/panxuejun/p/7715917.html 总结的非常好,一看就懂
为了方便查看,再写一遍方便自己日后看:
过滤器和拦截器的区别:
一、过滤器Filter是JavaEE标准,在Servlet的规范中定义的,是Servlet容器支持的,是属于Servlet容器的,依赖Servlet容器;拦截器Interceptor是Spring的组件之一,是属于Spring框架的,依赖于Spring框架,归Spring管理,配置在Spring的文件中,因此能使用Spring里的任何资源和对象,例如Service对象、数据源、事务管理等,所以可以通过Spring的IOC注入方式注入即可,而Filter不可以。
(若用配置文件方式配置,Filter配置在web.xml中,Interceptor配置在Spring MVC的配置文件中。多个过滤器的执行顺序跟在web.xml文件中定义的先后关系有关。多个拦截器它们之间的执行顺序跟在SpringMVC的配置文件中定义的先后顺序有关。)
二、 过滤器Filter是基于函数回调实现;拦截器是基于java的反射机制实现,属于面向切面编程(AOP)的一种运用。
三、拦截器(依赖Spring框架所以)只能对Controller请求进行拦截而对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理,而过滤器则可以对几乎所有的请求起作用。
四、拦截器(是Spring组件之一)所以可以访问action上下文、值栈里的对象,而过滤器不能访问。
五、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化是被调用一次。
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑
过滤器包裹住servlet,servlet包裹住拦截器
过滤器Filter
@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..."); }
拦截器Interceptor 继承HandlerInterceptor后如下
@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"); }
过滤器的触发时机是容器后,servlet之前,所以过滤器的doFilter(
ServletRequest request, ServletResponse response, FilterChain chain
)的入参是ServletRequest ,而不是httpservletrequest。因为过滤器是在httpservlet之前。
过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在chain.doFilter(request, response);这个方法中进行的。
a.preHandle()这个方法是在过滤器的chain.doFilter(request, response)方法的前一步执行,也就是在 [System.out.println("before...")][chain.doFilter(request, response)]之间执行。
b.postHandle()方法之后,在return ModelAndView之前进行,可以操控Controller的ModelAndView内容。
c.afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之间执行。
SpringMVC的机制是由同一个Servlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。所以过滤器、拦截器、service()方法,dispatch()方法的执行顺序应该是这样的。
灵活性上说拦截器功能更强大些,Filter能做的事情,Interceptor都能做,而且可以在请求前,请求后执行,异常抛出时,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。