天天看點

spring 過濾器 Filter簡介Filter工作原理常見問題1、@WebFilter配置Filter過濾器2、FilterRegistrationBean配置Filter過濾器測試用例

簡介

依賴于servlet容器。在實作上基于函數回調,可以對幾乎所有請求進行過濾,但是缺點是一個過濾器執行個體隻能在容器初始化時調用一次。

使用過濾器的目的是用來做一些過濾操作,擷取我們想要擷取的資料。

WEB開發人員通過Filter技術,對web伺服器管理的所有web資源:例如JSP,Servlet,靜态圖檔檔案或靜态HTML檔案進行攔截,進而實作一些特殊功能。例如實作URL級别的權限控制、過濾敏感詞彙、壓縮響應資訊、過濾器中修改字元編碼等一些進階功能。

Filter工作原理

當用戶端發出Web資源的請求時,Web伺服器根據應用程式配置檔案設定的過濾規則進行檢查,若客戶請求滿足過濾規則,則對客戶請求/響應進行攔截,對請求頭和請求資料進行檢查或改動,并依次通過過濾器鍊,最後把請求/響應交給請求的Web資源處理。請求資訊在過濾器鍊中可以被修改,也可以根據條件讓請求不發往資源處理器,并直接向客戶機發回一個響應。當資源處理器完成了對資源的處理後,響應資訊将逐級逆向傳回。同樣在這個過程中,使用者可以修改響應資訊,進而完成一定的任務

常見問題

Web開發中,自定義過濾器被執行兩次的原因分析。

導緻原因:第一次列印的是我請求的Servlet,第二次列印的是/favicon.ico

1、@WebFilter配置Filter過濾器

@Configuration//将此Filter交給Spring容器管理
@WebFilter(urlPatterns = "/*", filterName = "logFilter2")
@Order(1)//指定過濾器的執行順序,值越大越靠後執行
public class LogCostFilter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("過濾器2-init");
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("過濾器2-doFilter-前");
    long start = System.currentTimeMillis();
    filterChain.doFilter(servletRequest, servletResponse);
    System.out.println("LogFilter2 Execute cost=" + (System.currentTimeMillis() - start));
    System.out.println("過濾器2-doFilter-後");
}

@Override
public void destroy() {
    System.out.println("過濾器2-destroy");
}           

}

2、FilterRegistrationBean配置Filter過濾器

public class LogCostFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("過濾器1-init");
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("過濾器1-doFilter-前");
    long start = System.currentTimeMillis();
    filterChain.doFilter(servletRequest,servletResponse);
    System.out.println("LogFilter1 Execute cost="+(System.currentTimeMillis()-start));
    System.out.println("過濾器1-doFilter-後");
}

@Override
public void destroy() {
    System.out.println("過濾器1-destroy");
}
}
           

使用FilterRegistrationBean來完成配置

@Configuration
public class FilterConfig {

@Bean
public FilterRegistrationBean registFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new LogCostFilter());
    registration.addUrlPatterns("/*");
    registration.setName("LogCostFilter");
    registration.setOrder(1);
    return registration;
}
           

測試用例

@GetMapping("/filter/{id}")
public void filter(@PathVariable("id") Long id) {
    System.out.println("Controller方法--前");
    UserEntity userEntity = userService.findUserById(id);
    System.out.println("Controller方法--後");
}           

運作結構

spring 過濾器 Filter簡介Filter工作原理常見問題1、@WebFilter配置Filter過濾器2、FilterRegistrationBean配置Filter過濾器測試用例