當前位置:
首頁 > 知識 > SpringBoot | 第七章:過濾器、監聽器、攔截器

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系列教程,如有雷同,請多多包涵了。本文是作者在電腦前一字一句敲的,每一步都是實踐的。若文中有所錯誤之處,還望提出,謝謝。




系列






  • SpringBoot | 第一章:第一個 SpringBoot 應用



  • SpringBoot | 第二章:lombok 介紹及簡單使用



  • SpringBoot | 第三章:springboot 配置詳解



  • SpringBoot | 第四章:日誌管理



  • SpringBoot | 第五章:多環境配置



  • SpringBoot | 第六章:常用註解介紹及簡單使用




【關於投稿】




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




① 留言格式:


【投稿】+《 文章標題》+ 文章鏈接

② 示例:


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

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






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


關注「ImportNew」,提升Java技能


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 ImportNew 的精彩文章:

深入理解單例模式 ( 下 )
SpringBoot | 第二章:lombok 介紹及簡單使用

TAG:ImportNew |