歡迎光臨
每天分享高質量文章

SpringBoot | 第七章:過濾器、監聽器、攔截器

(點擊上方公眾號,可快速關註)


來源:oKong ,

blog.lqdev.cn/2018/07/19/springboot/chapter-seven/

前言

在實際開發過程中,經常會碰見一些比如系統啟動初始化信息、統計在線人數、在線用戶數、過濾敏高詞彙、訪問權限控制(URL級別)等業務需求。這些對於業務來說一般上是無關的,業務方是無需關係的,業務只需要關係自己內部業務的事情。所以一般上實現以上的功能,都會或多或少的用到今天準備講解的過濾器、監聽器、攔截器來實現以上功能。

過濾器

過濾器Filter,是Servlet的的一個實用技術了。可通過過濾器,對請求進行攔截,比如讀取session判斷用戶是否登錄、判斷訪問的請求URL是否有訪問權限(黑白名單)等。主要還是可對請求進行預處理。接下來介紹下,在springboot如何實現過濾器功能。

利用WebFilter註解配置

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

編寫Filter類:

//註冊器名稱為customFilter,攔截的url為所有

@WebFilter(filterName=”customFilter”,urlPatterns={“/*”})

@Slf4j

public class CustomFilter implements Filter{

 

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

        log.info(“filter 初始化”);

    }

 

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

            throws IOException, ServletException {

        // TODO Auto-generated method stub

        log.info(“doFilter 請求處理”);

        //對request、response進行一些預處理

        // 比如設置請求編碼

        // request.setCharacterEncoding(“UTF-8”);

        // response.setCharacterEncoding(“UTF-8”);

        //TODO 進行業務邏輯

         

        //鏈路 直接傳給下一個過濾器

        chain.doFilter(request, response);

    }

 

    @Override

    public void destroy() {

        log.info(“filter 銷毀”);

    }

}

然後在啟動類加入@ServletComponentScan註解即可。

@SpringBootApplication

@ServletComponentScan

@Slf4j

public class Chapter7Application {

     

    public static void main(String[] args) {

        SpringApplication.run(Chapter7Application.class, args);

        log.info(“chapter7 服務啟動”);

    }

}

啟動後,控制台輸出:

過濾器已經生效了。但當註冊多個過濾器時,無法指定執行順序的,原本使用web。xml配置過濾器時,是可指定執行順序的,但使用@WebFilter時,沒有這個配置屬性的(需要配合@Order進行),所以接下來介紹下通過FilterRegistrationBean進行過濾器的註冊。

–小技巧–

  1. 通過過濾器的名字,進行順序的約定,比如LogFilter和AuthFilter,此時AuthFilter就會比LogFilter先執行,因為首字母A比L前面。

  2. 通過@Order指定執行順序,值越小,越先執行

FilterRegistrationBean方式

FilterRegistrationBean是springboot提供的,此類提供setOrder方法,可以為filter設置排序值,讓spring在註冊web filter之前排序後再依次註冊。

改寫filter

其實就輸出了@webFilter註解即可。其他的都沒有變化。

啟動類中利用@bean註冊FilterRegistrationBean

@Bean

    public FilterRegistrationBean  filterRegistrationBean() {

        FilterRegistrationBean registration = new FilterRegistrationBean();

        //當過濾器有註入其他bean類時,可直接通過@bean的方式進行物體類過濾器,這樣不可自動註入過濾器使用的其他bean類。

        //當然,若無其他bean需要獲取時,可直接new CustomFilter(),也可使用getBean的方式。

        registration.setFilter(customFilter());

        //過濾器名稱

        registration.setName(“customFilter”);

        //攔截路徑

        registration.addUrlPatterns(“/*”);

        //設置順序

        registration.setOrder(10);

        return registration;

    }

 

    @Bean

    public Filter customFilter() {

        return new CustomFilter();

    }

註冊多個時,就註冊多個FilterRegistrationBean即可

啟動後,效果和第一種是一樣的。

監聽器

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

創建一個ServletRequest監聽器(其他監聽器類似創建)

@WebListener

@Slf4j

public class Customlister implements ServletRequestListener{

 

    @Override

    public void requestDestroyed(ServletRequestEvent sre) {

        log.info(“監聽器:銷毀”);

    }

 

    @Override

    public void requestInitialized(ServletRequestEvent sre) {

        log.info(“監聽器:初始化”);

    }

 

}

和創建過濾器一樣,在啟動類中加入@ServletComponentScan進行自動註冊即可。

攔截器

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

編寫自定義攔截器類

@Slf4j

public class CustomHandlerInterceptor implements HandlerInterceptor{

 

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

            throws Exception {

        log.info(“preHandle:請求前呼叫”);

        //傳回 false 則請求中斷

        return true;

    }

 

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

            ModelAndView modelAndView) throws Exception {

        log.info(“postHandle:請求後呼叫”);

 

    }

 

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

            throws Exception {

        log.info(“afterCompletion:請求呼叫完成後回呼方法,即在視圖渲染完成後回呼”);

 

    }

}

通過繼承WebMvcConfigurerAdapter註冊攔截器

@Configuration

public class WebMvcConfigurer extends WebMvcConfigurerAdapter{

     

    @Override

     public void addInterceptors(InterceptorRegistry registry) {

         //註冊攔截器 攔截規則

        //多個攔截器時 以此添加 執行順序按添加順序

        registry.addInterceptor(getHandlerInterceptor()).addPathPatterns(“/*”);

     }

     

    @Bean

    public static HandlerInterceptor getHandlerInterceptor() {

        return new CustomHandlerInterceptor();

    }

}

啟動後,訪問某個url,控制台輸出

請求鏈路說明

在整個請求的過程,此一圖勝千言,希望對此有個深刻的瞭解,通過不同組合實現不同的業務功能。

總結

本章節主要介紹了常用web開發時,會用到的一些常用類,本章節對servlet未進行介紹,平時用的比較少,用法和配置其實和攔截器、監聽器是類似的,再次就不闡述了。

最後

目前互聯網上很多大佬都有SpringBoot系列教程,如有雷同,請多多包涵了。本文是作者在電腦前一字一句敲的,每一步都是實踐的。若文中有所錯誤之處,還望提出,謝謝。

系列


【關於投稿】


如果大家有原創好文投稿,請直接給公號發送留言。


① 留言格式:
【投稿】+《 文章標題》+ 文章鏈接

② 示例:
【投稿】《不要自稱是程式員,我十多年的 IT 職場總結》:http://blog.jobbole.com/94148/

③ 最後請附上您的個人簡介哈~



看完本文有收穫?請轉發分享給更多人

關註「ImportNew」,提升Java技能

赞(0)

分享創造快樂