Filter和Intercepter區別和使用

  • 過濾器(Filter)

    依賴於Servlet容器(因此不能使用spring容器的資源)
    實現是基於函數回調
    能夠對全部請求進行過濾java

  • 攔截器(Intercepter)

    依賴於web容器(可使用spring容器的資源)
    實現是基於反射
    只能對controller請求進行攔截,對直接訪問靜態資源的請求沒法攔截git

執行順序

Filter前處理->Intercepteor前處理->action->Interceptor後處理->Filter後處理github

Filter的做用

  • 在HttpServletRequest到達Servlet以前,檢查,修改甚至攔截HttpServletRequest。
  • 在HttpServletResponse到達客戶端以前,修改或攔截HttpServletResponse。
  • 檢查用戶請求,根據請求過濾用戶非法請求。
  • 詳細記錄某些特殊的用戶請求。
  • 對非標準編碼的請求解碼

Inteceptor的做用

  1. 日誌記錄:記錄請求信息的日誌,以便進行信息監控、信息統計、計算 PV(Page View)等;
  2. 權限檢查:如登陸檢測,進入處理器檢測是否登陸;
  3. 性能監控:經過攔截器在進入處理器以前記錄開始時間,在處理完後記錄結束時間,從而獲得該請求的處理時間。(反向代理,如 Apache 也能夠自動記錄)
  4. 通用行爲:讀取 Cookie 獲得用戶信息並將用戶對象放入請求,從而方便後續流程使用,還有如提取 Locale、Theme 信息等,只要是多個處理器都須要的便可使用攔截器實現

javax.servlet.Filter接口:

  • void init(FilterConfig config):Filter的初始化。
  • void destory():Filter銷燬前,資源的回收。
  • void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):在調用chain.doFilter()方法前能夠對request進行預處理,在調用chain.doFilter()方法後能夠對response進行後處理

HandlerInterceptor接口:

  • preHandle在請求處理以前進行調用。能夠在這個方法中進行初始化或預處理或判斷來決定請求是否要繼續進行下去。web

    • 返回值爲true時表示繼續執行,會繼續調用下一個Interceptor 的preHandle 方法,若是已是最後一個Interceptor 的時候就會是調用當前請求的Controller方法
    • 返回爲false 時,表示請求結束,後續的Interceptor 和Controller 都不會再執行
  • postHandle preHandle 方法的返回值爲true 時才能被調用postHandle 方法,Controller 方法調用以後執行,可是它會在DispatcherServlet 進行視圖返回渲染以前被調用,因此咱們能夠在這個方法中對Controller 處理以後的ModelAndView 對象進行操做
  • afterCompletion在整個請求結束以後,也就是在DispatcherServlet 渲染了對應的視圖以後執行。這個方法的主要做用是用於進行資源清理工做的。

Filter實現

public class MyFilter1 implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(MyFilter1.class);
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("***************MyFilter1 init******************");
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        logger.info("------------MyFilter1-doFilter before---------");
        logger.info("-------" + request.getRemoteAddr() + ":" +request.getRemotePort() + "--------");
        String usrId = request.getParameter("usrId");
        if((usrId == null)||(usrId.isEmpty())||(Integer.parseInt(usrId)<=0)) {
            HttpServletResponse httpResponse = (HttpServletResponse)response;
            httpResponse.getWriter().print("Parameter error!");
        } else if(Integer.parseInt(usrId) >=1000) {
            chain.doFilter(request, response);
        }
        logger.info("------------MyFilter1-doFilter after---------");
    }
    
    @Override
    public void destroy() {
        logger.info("***************MyFilter1 destroy******************");
    }
}

Interceptor實現spring

public class LogInterceptor implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
    
    @Autowired
    UserPrivilegeService privilegeService;
    
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        logger.info("*********** LogInterceptor preHandle *******************");
        long startTime = System.currentTimeMillis();
        httpServletRequest.setAttribute("startTime", startTime);
        return true; 
    }
    
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        logger.info("*********** LogInterceptor postHandle *******************");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        logger.info("*********** LogInterceptor afterCompletion *******************");
        long startTime = (Long) httpServletRequest.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        logger.info("End Time: " + endTime);
        logger.info("Time Taken: " + (endTime - startTime));
    }
}

添加Filter

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean1(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new MyFilter1());
        bean.addUrlPatterns("/login");
        bean.setOrder(1); //值越小優先級越高
        return bean;
    }
 }

添加Interceptor

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor());
    }
}

測試代碼ide

相關文章
相關標籤/搜索