在實際開發過程當中,常常會遇見一些好比系統啓動初始化信息、統計在線人數、在線用戶數、過濾敏高詞彙、訪問權限控制(URL級別)等業務需求。這些對於業務來講通常上是無關的,業務方是無需關係的,業務只須要關係本身內部業務的事情。因此通常上實現以上的功能,都會或多或少的用到今天準備講解的
過濾器
、監聽器
、攔截器
來實現以上功能。java
過濾器
Filter
,是Servlet
的的一個實用技術了。可經過過濾器,對請求進行攔截,好比讀取**session
判斷用戶是否登陸**、判斷訪問的**請求URL是否有訪問權限(黑白名單)**等。主要仍是可對請求進行預處理。接下來介紹下,在springboot
如何實現過濾器功能。git
@WebFilter
時Servlet3.0
新增的註解,原先實現過濾器,須要在web.xml
中進行配置,而如今經過此註解,啓動啓動時會自動掃描自動註冊。github
編寫Filter類:web
//註冊器名稱爲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
註解便可。spring
@SpringBootApplication @ServletComponentScan @Slf4j public class Chapter7Application { public static void main(String[] args) { SpringApplication.run(Chapter7Application.class, args); log.info("chapter7 服務啓動"); } }
啓動後,控制檯輸出:api
過濾器已經生效了。但當註冊多個過濾器時,沒法指定執行順序的,本來使用web。xml
配置過濾器時,是可指定執行順序的,但使用@WebFilter
時,沒有這個配置屬性的(須要配合@Order
進行),因此接下來介紹下經過FilterRegistrationBean
進行過濾器的註冊。springboot
--小技巧--(2018-08-25修訂)session
LogFilter
和AuthFilter
,此時AuthFilter
就會比LogFilter
先執行,由於首字母A
比L
前面。可查看具體緣由:《關於@webFilter使用@Order無效問題》ide
FilterRegistrationBean
是springboot
提供的,此類提供setOrder方法,能夠爲filter設置排序值,讓spring在註冊web filter以前排序後再依次註冊。spring-boot
改寫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
系列教程,若有雷同,請多多包涵了。本文是做者在電腦前一字一句敲的,每一步都是實踐的。若文中有所錯誤之處,還望提出,謝謝。
499452441
lqdevOps
完整實例地址:chapter-7