过滤器 (Filter) 和 拦截器 (Interceptor)
1、过滤器 (Filter)
实现Filter接口即可,通过@WebFilter注解实现;
Filter接口中定义了三个方法。
init():在容器启动初始化过滤器时被调用,整个生命周期只会被调用一次
doFilter():容器中的每一次请求都会调用该方法,FilterChain用来调用下一个过滤器Filter。
destroy():当容器销毁过滤器实例时调用该方法,一般用作销毁或者关闭资源,整个生命周期只会被调用一次
2、拦截器 (Interceptor)
拦截器是链式调用,应用中可以同时存在多个拦截器,一个请求也可以触发多个拦截器,而拦截器的调用会依据声明顺序
拦截器是通过HandlerInterceptor来实现,HandlerInterceptor 接口中定义了三个方法
preHandle():在请求处理之前进行调用,程序先执行preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行
postHandle():业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应;postHandle()调用的顺序跟preHandle()相反的
afterCompletion():在DispatcherServlet处理完请求后,才会执行afterCompletion()方法。
3、二者的不同点
两者同时存在时,过滤器包裹住servlet,servlet包裹住拦截器。
(1) 实现原理不同
过滤器是JavaEE标准,拦截器是Spring容器的
过滤器和拦截器 底层实现方式大不相同,过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的。
(2) 触发时机不同
过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。
过滤器与servlet绑定,只能对action请求起作用,拦截器不依赖servlet,可以对所有请求起作用
拦截器可以获取IOC容器的各个Bean。过滤器不行。