SpringBoot第五集:整合監聽器/過濾器和攔截器(2020最新最易懂)
SpringBoot第五集:整合監聽器/過濾器和攔截器(2020最新最易懂)
在實際開發過程中,經常會碰見一些比如系統啟動初始化資訊、統計線上人數、線上使用者數、過濾敏/高詞彙、訪問許可權控制(URL級別)等業務需求。實現以上的功能,都會或多或少的用到過濾器
、監聽器
、攔截器
。
一.SpringBoot整合過濾器Filter
過濾器Filter
,是Servlet
的的一個實用技術了。可以通過過濾器,對請求進行攔截處理。
1.編寫Filter過濾器
- 編寫普通Java類實現介面Filter。
- 使用註解@WebFilter標註過濾器類,並配置過濾url。
1 @WebFilter("/*")// 當前配置攔截所有請求
說明:@WebFilter
時Servlet3.0
新增的註解,原先實現過濾器,需要在web.xml
中進行配置,而現在通過此註解,啟動啟動時會自動掃描自動註冊。 - 在啟動類加入
@ServletComponentScan
註解
使用@ServletComponentScan註解後,Servlet、Filter、Listener可以直接通過@WebServlet、@WebFilter、@WebListener註解自動註冊。 - 開啟啟動類,訪問測試,檢視控制檯結果
當註冊多個過濾器時,無法指定執行順序,早期使用
web.xml
配置過濾器時,是可指定執行順序,但使用註解@WebFilter
時,沒有順序這個配置屬性。通常情況下,如果對過濾器有特定順序要求的,我們推薦採用原始方式配置,或者參考測試結果:執行順序和類名字元排序有關。另外SpringBoot也為解決這個問題,單獨提供了一個類FilterRegistrationBean,此類提供setOrder方法,可以為filter設定排序值,讓Spring在註冊Filter之前排序後再依次註冊。
2.解決多過濾器執行順序問題
- 編寫兩個/以上Filter,修改Filter的實現(去除註解@WebFilter即可,其他程式碼無需改動)
- 編寫一個config配置類,利用FilterRegistrationBean實現註冊過濾器。
FilterRegistrationBean是SpringBoot提供的用於註冊和解決Filter執行順序問題的類。注意在類上使用註解@Configuration,在方法上使用註解@Bean。
1 @Configuration // 標註為Spring配置beans元件 2 public class FilterConfig { 3 4 // 註冊第一個Filter 5 @Bean // 標註為Spring配置bean元件 6 public FilterRegistrationBean<Filter> registerFilter1() { 7 //通過FilterRegistrationBean例項設定優先順序可以生效 8 FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>(); 9 // 註冊自定義過濾器 10 registrationBean.setFilter(new TestFilter1()); 11 // 設定過濾器的名字<filter-name> 12 registrationBean.setName("filter01"); 13 // 設定過濾器的名字過濾路徑<url-partten> 14 registrationBean.addUrlPatterns("/*"); 15 // 設定過濾器優先順序:最頂級 16 registrationBean.setOrder(1); 17 return registrationBean; 18 } 19 20 @Bean 21 public FilterRegistrationBean<Filter> registerFilter2() { 22 FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>(); 23 // 註冊第二個自定義過濾器TestFilter2 24 registrationBean.setFilter(new TestFilter2()); 25 registrationBean.setName("filter02"); 26 registrationBean.addUrlPatterns("/*"); 27 registrationBean.setOrder(5); 28 return registrationBean; 29 } 30 31 }
- 開啟啟動類,訪問測試,檢視控制檯結果
說明:這種方式可以不使用註解@ServletComponentScan
二.SpringBoot整合監聽器Listnner
Listnner是servlet規範中定義的一種特殊類。用於監聽ServletContext、HttpSession和servletRequest等域物件的建立和銷燬事件。監聽域物件的屬性發生修改的事件。用於在事件發生前、發生後做一些必要的處理。一般是獲取線上人數等業務需求。
- 建立普通類實現監聽器介面(比較多,我就不一一列出了)
本次案例:建立了ServletRequest監聽器,實現介面ServletRequestListnner
1 @WebListener 2 @Slf4j // 該註解等價於Logger log = new Logger(。。。。) 3 public class TestListnner implements ServletRequestListener { 4 @Override 5 public void requestInitialized(ServletRequestEvent sre) { 6 log.info("ServletRequest出生…………"); 7 } 8 9 @Override 10 public void requestDestroyed(ServletRequestEvent sre) { 11 log.info("ServletRequest銷燬…………"); 12 } 13 }
- 在啟動類加入
@ServletComponentScan
註解
使用@ServletComponentScan註解後,Servlet、Filter、Listener可以直接通過@WebServlet、@WebFilter、@WebListener註解自動註冊。 - 開啟啟動類,訪問測試,檢視控制檯結果
三.SpringBoot整合攔截器HandlerInterceptor
以上的過濾器、監聽器都屬於Servlet的API,我們在開發中過濾web請求時,還可以使用Spring
提供的攔截器(HandlerInterceptor
)進行更加精細的控制。
- 編寫普通類實現介面HandlerInterceptor。
1 @Slf4j 2 public class TestHandlerInterceptor implements HandlerInterceptor { 3 4 @Override 5 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 6 throws Exception { 7 log.info("preHandle請求訪問前,攔截執行……"); 8 // 返回 false 則請求中斷 9 return true; 10 } 11 12 @Override 13 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 14 ModelAndView modelAndView) throws Exception { 15 log.info("postHandle請求訪問後,執行……"); 16 } 17 18 @Override 19 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 20 throws Exception { 21 log.info("afterCompletion請求呼叫完成後回撥方法,即在檢視渲染完成後回撥……"); 22 } 23 24 }
- 編寫普通類繼承
WebMvcConfigurerAdapter註解攔截器
WebMvcConfigurerAdapter配置類是spring提供的一種配置方式,採用JavaBean的方式替代傳統的基於xml的配置來對spring框架進行自定義的配置,可以自定義一些Handler,Interceptor,ViewResolver,MessageConverter。因此,在spring boot提倡的基於註解的配置,採用“約定大於配置”的風格下,當需要進行自定義的配置時,便可以繼承WebMvcConfigurerAdapter這個抽象類,通過JavaBean來實現需要的配置。
WebMvcConfigurerAdapter是一個抽象類,它只提供了一些空的介面讓使用者去重寫,比如如果想新增攔截器的時候,需要去重寫一下addInterceptors()這個方法,去配置自定義的攔截器。我們可以看一下WebMvcConfigurerAdapter提供了哪些介面來供我們使用。1 public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { 2 /*配置路徑匹配引數*/ 3 public void configurePathMatch(PathMatchConfigurer configurer) {} 4 /*配置Web Service或REST API設計中內容協商,即根據客戶端的支援內容格式情況來封裝響應訊息體,如xml,json*/ 5 public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {} 6 /*配置路徑匹配引數*/ 7 public void configureAsyncSupport(AsyncSupportConfigurer configurer) {} 8 /* 使得springmvc在介面層支援非同步*/ 9 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {} 10 /* 註冊引數轉換和格式化器*/ 11 public void addFormatters(FormatterRegistry registry) {} 12 /* 註冊配置的攔截器*/ 13 public void addInterceptors(InterceptorRegistry registry) {} 14 /* 自定義靜態資源對映*/ 15 public void addResourceHandlers(ResourceHandlerRegistry registry) {} 16 /* cors跨域訪問*/ 17 public void addCorsMappings(CorsRegistry registry) {} 18 /* 配置頁面直接訪問,不走介面*/ 19 public void addViewControllers(ViewControllerRegistry registry) {} 20 /* 註冊自定義的檢視解析器*/ 21 public void configureViewResolvers(ViewResolverRegistry registry) {} 22 /* 註冊自定義控制器(controller)方法引數型別*/ 23 public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {} 24 /* 註冊自定義控制器(controller)方法返回型別*/ 25 public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {} 26 /* 過載會覆蓋掉spring mvc預設註冊的多個HttpMessageConverter*/ 27 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {} 28 /* 僅新增一個自定義的HttpMessageConverter,不覆蓋預設註冊的HttpMessageConverter*/ 29 public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {} 30 /* 註冊異常處理*/ 31 public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {} 32 /* 多個異常處理,可以重寫次方法指定處理順序等*/ 33 public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {} 34 }
Spring 5.0/SpringBoot 2.0 後,WebMvcConfigurerAdapter被廢棄,取代的方法有兩種:
①implements WebMvcConfigurer(官方推薦)
②extends WebMvcConfigurationSupport
1 @Configuration // 標註為Spring元件 2 public class HandlerInterceptorConfig implements WebMvcConfigurer { 3 @Override 4 public void addInterceptors(InterceptorRegistry registry) { 5 // 新增一個實現HandlerInterceptor介面的攔截器例項 6 registry.addInterceptor(new TestHandlerInterceptor()) 7 // 用於設定攔截器的過濾路徑規則 8 .addPathPatterns("/**") 9 // 用於設定不需要攔截的過濾規則 10 .excludePathPatterns("/emp/toLogin","/emp/login", "/js/**", "/css/**", "/images/**"); 11 } 12 }
注意在類上添加註解@Configuration標註為Spring元件
- 開啟啟動類,訪問測試,檢視控制檯結果
一張圖理解過濾器,攔截器執行
目前網際網路上很多大佬都有SpringBoot
系列教程,如有雷同,請多多包涵了。畫圖太費事了,圖片來源於網路。