SpringBoot之過濾器和攔截器
一、淺析過濾器和攔截器
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
介面。
/**
* preHandle()方法 - 用於在將請求傳送到控制器之前執行操作。此方法應返回true,以將響應返回給客戶端。
* postHandle()方法 - 用於在將響應傳送到客戶端之前執行操作。
* afterCompletion()方法 - 用於在完成請求和響應後執行操作
*/
@Component
public class LoginHandlerInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(HandlerInterceptor.class);
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("Pre Handle method is Calling");
return true;
}
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("Post Handle method is Calling");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws Exception {
logger.info("Request and Response is completed");
}
}
2、使用WebMvcConfigurerAdapter
向InterceptorRegistry
註冊此Interceptor
@Configuration
public class LoginHandlerInterceptorAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//註冊LoginHandlerInterceptor攔截器
InterceptorRegistration registration = registry.addInterceptor(new LoginHandlerInterceptor());
//所有路徑都被攔截
registration.addPathPatterns("/**");
}
}
四、測試
訪問介面控制檯列印: