項目中會用到過濾器(Filter)和攔截器(Interceptor)。
首先看一下這兩者之間的包含關係:
如上圖所示,二者之間的觸發時機不同:
執行順序爲: 過濾前-攔截前-action執行-攔截後-過濾後
1. 過濾器:
過濾器是JavaEE標準,基於函數回調。主要對客戶請求做預處理。
過濾器的觸發是在請求進入容器後,且請求進入servlet之前進行預處理的。所以請求結束返回是在servlet處理完之後,返給前端之前。
由於觸發是在容器之後,servlet之前,所以filter的傳參是servlet而不是 httpservlet
@Component
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
filterChain.doFilter(request, response);這個方法的調用作爲分水嶺。事實上調用Servlet的doService()方法是在filterChain.doFilter(request, response);這個方法中進行的。
2. 攔截器:
攔截器是spring容器的,由spring支持。是AOP的一種實現策略。
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
preHandle()是在過濾器 filterChain.doFilter(request, response);方法的前一步執行,
postHandle()是在方法請求之間 進行,
afterCompletion()方法是在過濾器返回給前端前一步執行,即filterChain.doFilter(request, response)方法之後執行,
springmvc的機制是由同一個Servlet分發請求給不同的Controller,這一步其實是在Servlet的service方法中執行的。
主要區別:
1. 攔截器基於Java反射機制, 過濾器基於函數回調,是javaEE的標準。
2. 攔截器不依賴於servlet,過濾器不依賴於servlet。
3. 攔截器只對action請求起作用,過濾器對幾乎所有請求起作用。
4. 攔截器可以訪問action上下文,值棧裏的對象, 過濾器不能訪問。
5. 在action的生命週期中,攔截器可以被多次調用,過濾器只能容器初始化時調用一次。
6. 攔截器可以獲取IOC容器的各個bean,即可以在攔截器注入service層,調用邏輯層代碼, 過濾器不行。