SpringBoot第六集:整合監聽器/過濾器和攔截器(2021最新最易懂)


SpringBoot第六集:整合監聽器/過濾器和攔截器(2021最新最易懂)

  在實際開發過程中,經常會碰見一些比如系統啟動初始化信息、統計在線人數、在線用戶數、過濾敏/高詞匯、訪問權限控制(URL級別)等業務需求。實現以上的功能,都會或多或少的用到過濾器監聽器攔截器

一.SpringBoot整合過濾器Filter  

  過濾器Filter,是Servlet的的一個實用技術了。可以通過過濾器,對請求進行攔截處理。

1.編寫Filter過濾器

  1. 編寫普通Java類實現接口Filter。
  2. 使用注解@WebFilter標注過濾器類,並配置過濾url。
     1 @WebFilter("/*")// 當前配置攔截所有請求
     2 public class TestFilter implements Filter {
     3 
     4     @Override
     5     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
     6             throws IOException, ServletException {
     7         System.out.println("過濾器Filter測試執行…………");
     8         chain.doFilter(request, response);// 放行
     9     }
    10 
    11 }

    說明:@WebFilterServlet3.0新增的注解,原先實現過濾器,需要在web.xml中進行配置,而現在通過此注解,啟動啟動時會自動掃描自動注冊。

  3. 在啟動類加入@ServletComponentScan注解
    使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通過@WebServlet、@WebFilter、@WebListener注解自動注冊。
  4. 開啟啟動類,訪問測試,查看控制台結果

當注冊多個過濾器時,無法指定執行順序,早期使用web.xml配置過濾器時,是可指定執行順序,但使用注解@WebFilter時,沒有順序這個配置屬性。通常情況下,如果對過濾器有特定順序要求的,我們推薦采用原始方式配置,或者參考測試結果:執行順序和類名字符排序有關。另外SpringBoot也為解決這個問題,單獨提供了一個類FilterRegistrationBean,此類提供setOrder方法,可以為filter設置排序值,讓Spring在注冊Filter之前排序后再依次注冊。

2.解決多過濾器執行順序問題

  1. 編寫兩個/以上Filter,修改Filter的實現(去除注解@WebFilter即可,其他代碼無需改動)
  2. 編寫一個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 }
  3. 開啟啟動類,訪問測試,查看控制台結果
    說明:這種方式可以不使用注解@ServletComponentScan

二.SpringBoot整合監聽器Listnner

  Listnner是servlet規范中定義的一種特殊類。用於監聽ServletContext、HttpSession和servletRequest等域對象的創建和銷毀事件。監聽域對象的屬性發生修改的事件。用於在事件發生前、發生后做一些必要的處理。一般是獲取在線人數等業務需求。

  1. 創建普通類實現監聽器接口(比較多,我就不一一列出了)
    本次案例:創建了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 }
  2. 在啟動類加入@ServletComponentScan注解
    使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通過@WebServlet、@WebFilter、@WebListener注解自動注冊。
  3. 開啟啟動類,訪問測試,查看控制台結果

三.SpringBoot整合攔截器HandlerInterceptor

  以上的過濾器、監聽器都屬於Servlet的API,我們在開發中過濾web請求時,還可以使用Spring提供的攔截器(HandlerInterceptor)進行更加精細的控制。

  1. 編寫普通類實現接口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 }
  2. 編寫普通類繼承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組件

  3. 開啟啟動類,訪問測試,查看控制台結果

一張圖理解過濾器,攔截器執行

 

 目前互聯網上很多大佬都有SpringBoot系列教程,如有雷同,請多多包涵了。畫圖太費事了,圖片來源於網絡。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM