Filter的說明
過濾器Filter是對目標資源的請求和響應進行攔截,對攔截到的請求和響應做出特殊的功能處理,如用統一處理請求權限,日誌記錄,敏感信息屏蔽,參數校驗等。
Filter的原理
Java過濾器是JavaWeb的三大組件(Filter,Servlet,Listener)之一,Java Servlet API中提供了Filter接口,編寫Filter的實現類,從而實現自定義過濾器。Filter的請求流程爲:
1 客戶端發起請求
2 服務容器判斷當前請求資源是否有過濾器,有則執行過濾器
3 過濾器過濾通過後請求到Servlet服務器
4 返回結果通過過濾器返回給請求方
Filter生命週期
看下Filter接口源碼
public interface Filter {
void init(FilterConfig var1) throws ServletException;
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
void destroy();
}
在程序啓動時,創建Filter對象,並調用init方法完成Filter初始化,並交由容器管理,常駐內存,在請求發起時,調用doFilter啓動對Servlet攔截,過濾通;在程序關閉時調用destroy方法,釋放資源,銷燬Filter。
Springboot Filter實現
Springboot有兩種自定義過濾器的方式
1 @WebFilter和@ServletComponentScan組合使用
如下自定義一個過濾器:
@WebFilter(filterName = "requestFilter")
public class RequestFilter implements Filter {
/**
* 實現doFilter方法,
* 過濾的具體功能在此處處理
*
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if ((servletRequest).getParameter("OK").equalsIgnoreCase("true")) {
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
在Springboot啓動器中添加@ServletComponentScan即可實現過濾器功能:
@SpringBootApplication
@ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
如果需要添加多個過濾器,只需添加多個實現FIlter功能的過濾器。但是這種方式過濾器過濾順序只能根據過濾器名的類名順序執行,添加@Order註解是無效的,原因是@WebFilter在容器加載時,不會使用@Order註解定義的順序,而是默認直接使用類名排序。所以使用這種方式實現多個過濾器,且有順序要求,則需要注意類名的定義。
2 實現Filter,通過自定義配置類配置Filter
實現Filter與上面RequestFilter相同,只是不添加@WebFilter,同時啓動器也不添加@ServletComponentScan,自定義配置類方式如下:
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Resource
private RequestFilter requestFilter;
@Bean
public FilterRegistrationBean requestFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(requestFilter);
registration.setName("requestFilter");
registration.setOrder(1);
return registration;
}
}
如果要實現多個過濾器,同時保持自定義順序,只需對配置文件註冊過濾器中的Order改變順序。註冊多個過濾器,只需要在配置類中創建多個Bean。