(點選上方公眾號,可快速關註)
來源: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進行過濾器的註冊。
–小技巧–
-
透過過濾器的名字,進行順序的約定,比如LogFilter和AuthFilter,此時AuthFilter就會比LogFilter先執行,因為首字母A比L前面。
-
透過@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技能