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隻能初始化時調用一次。