Intercept
拦截器的主要作用是拦截请求,进行处理,比如用户登录,权限校验,主要针对Action请求进行处理。
拦截器的实现可以继承HandlerInterceptorAdapter
或者实现HandlerInterceptor
接口
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion");
}
}
- preHandle方法实在请求到达controller之前执行,可以进行用户校验登录等操作,返回true之后,请求到达Controller层;
- postHandle方法是在执行完controller层的代码之后,DispatcherServlet进行视图渲染之前执行,因此可以对ModelAndView对象进行操作;
- afterCompletion方法是在DispatcherServlet进行视图渲染之后才调用,主要进行一些资源清理的工作。
- 转发和重定向并不能改变拦截链的执行顺序。最后的afterCompletion方法还是会执行
Filter
过滤器的主要作用是过滤请求,可以统一设置字符集等。
但是过滤器依赖Servlet容器,并且只能在容器初始化的时候调用一次。
public class TestFilter implements Filter {
@Override
public void destroy() {
System.out.println("filter destroy");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
System.out.println("filter doFilter before");
arg2.doFilter(arg0, arg1);
System.out.println("filter doFilter after");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("filter init");
}
}
- init方法实在servlet容器启动的时候执行一次。
- destory方法在容器关闭的时候执行。
- doFilter方法就是过滤请求,只有执行完doFilter方法请求才会放行。
拦截器和过滤器的执行顺序
1、Filter.init();
2、Filter.doFilter(); before doFilter
3、HandlerInterceptor.preHandle();
4、Controller方法执行
5、HandlerInterceptor.postHandle();
6、DispatcherServlet视图渲染
7、HandlerInterceptor.afterCompletion();
8、Filter.doFilter(); after doFilter
9、Filter.destroy();
Filter和Interceptor的区别
- 过滤器是基于函数回调的,拦截器是基于Java反射的。(Spring AOP)
- 过滤器依赖servlet,拦截器不依赖
- 过滤器对所有的请求都起作用,拦截器只对action请求起作用
- 拦截器可以访问action的上下文,以及栈里面的对象,但过滤器不可以
- 在action的生命周期里,拦截器可以被多次调用,但Filter只能初始化时调用一次。