簡介
依賴于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方法--後");
}
運作結構
