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

前言

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

過濾器

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

利用WebFilter註解配置

@WebFilterServlet3.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

  1. 經過過濾器的java類名稱,進行順序的約定,好比LogFilterAuthFilter,此時AuthFilter就會比LogFilter先執行,由於首字母AL前面。

可查看具體緣由:《關於@webFilter使用@Order無效問題》ide


FilterRegistrationBean方式

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

老生常談

  • 我的QQ:499452441
  • 公衆號:lqdevOps

公衆號

我的博客:https://blog.lqdev.cn

完整實例地址:chapter-7

相關文章
相關標籤/搜索