一、淺析過濾器和攔截器
1、過濾器:
它依賴於servlet容器。它可以對幾乎所有請求進行過濾,但是缺點是一個過濾器實例只能在容器初始化時調用一次。使用過濾器的目的,是用來做一些過濾操作,獲取我們想要獲取的數據,比如:在Javaweb中,對傳入的request、response提前過濾掉一些信息,或者提前設置一些參數,然后再傳入servlet或者Controller進行業務邏輯操作。通常用的場景是:在過濾器中修改字符編碼(CharacterEncodingFilter)、在過濾器中修改HttpServletRequest的一些參數(XSSFilter(自定義過濾器)),如:過濾低俗文字、危險字符等。
2、攔截器:
它依賴於web框架,在SpringMVC中就是依賴於SpringMVC框架。在實現上,基於Java的反射機制,屬於面向切面編程(AOP)的一種運用,就是在service或者一個方法前,調用一個方法,或者在方法后,調用一個方法,比如動態代理就是攔截器的簡單實現,在調用方法前打印出字符串(或者做其它業務邏輯的操作),也可以在調用方法后打印出字符串,甚至在拋出異常的時候做業務邏輯的操作。由於攔截器是基於web框架的調用,因此可以使用Spring的依賴注入(DI)進行一些業務操作,同時一個攔截器實例在一個controller生命周期之內可以多次調用。攔截器可以對靜態資源的請求進行攔截處理。
3、區別:
1)Filter是依賴於Servlet容器,屬於Servlet規范的一部分,而攔截器則是獨立存在的,可以在任何情況下使用。
2)Filter的執行由Servlet容器回調完成,而攔截器通常通過動態代理的方式來執行。
3)Filter的生命周期由Servlet容器管理,而攔截器則可以通過IoC容器來管理,因此可以通過注入等方式來獲取其他Bean的實例,因此使用會更方便。
二、建立過濾器
1、創建過濾器TestFilter
@Order(1)
@WebFilter(filterName = "testFilter", urlPatterns = "/*" , initParams = {
@WebInitParam(name = "URL", value = "http://localhost:8080")})
public class TestFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(TestFilter.class);
/**
* init : filter對象只會創建一次,init方法也只會執行一次。
* doFilter : 主要的業務代碼編寫方法,可以多次重復調用
* destroy : 在銷毀Filter時自動調用(程序關閉或者主動銷毀Filter)
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
logger.info("================Remote Host:" + servletRequest.getRemoteHost());
logger.info("================Remote Address:" + servletRequest.getRemoteAddr());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
注:
@Order(1):表示過濾器的順序,假設我們有多個過濾器,你如何確定過濾器的執行順序?這個注解就是規定過濾器的順序。
@WebFilter:表示這個class是過濾器。里面的參數:filterName 為過濾器名字,urlPatterns 為過濾器的范圍,initParams 為過濾器初始化參數。
2、在啟動類上添加注解@ServletComponentScan

補:可以直接在過濾器類上添加注解@Component,無須再在啟動類上添加注解,spring也會自動加載
三、建立攔截器
1、創建自定義攔截器
要使用攔截器,需要創建支持它的@Component類,它應該實現HandlerInterceptor
接口。
2、創建Config並繼承WebMvcConfigurer,將此Interceptor注冊到InteceptorRegistry中去

@Configuration
public class LoginHandlerInterceptorAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注冊LoginHandlerInterceptor攔截器
InterceptorRegistration registration = registry.addInterceptor(new LoginHandlerInterceptor());
//所有路徑都被攔截
registration.addPathPatterns("/**");
}
}
四、測試
訪問接口控制台打印: