1. 程式人生 > >SpringBoot攔截器Interceptor

SpringBoot攔截器Interceptor

java裡的攔截器是動態攔截Action呼叫的物件,它提供了一種機制可以使開發者在一個Action執行的前後執行一段程式碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分程式碼的方式。在AOP中,攔截器用於在某個方法或者欄位被訪問之前,進行攔截然後再之前或者之後加入某些操作。目前,我們需要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道即可。。

一:攔截器的應用場景

1、日誌記錄:記錄請求資訊的日誌,以便進行資訊監控、資訊統計、計算PV(Page VIEW)等。 2、許可權檢查:如登入檢測,進入處理器檢測檢測是否登入,如果沒有直接返回到登入頁面; 3、效能監控:有時候系統在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如apache可以自動記錄); 4、通用行為:讀取cookie得到使用者資訊並將使用者物件放入請求,從而方便後續流程使用,還有如提取Locale、Theme資訊等,只要是多個處理器都需要的即可使用攔截器實現。 5、OpenSessionInView:如Hibernate,在進入處理器開啟SESSION,在完成後關閉SESSION。

二:攔截器與過濾器的區別

1、攔截器是基於Java的反射機制的,而過濾器是基於函式回撥。 2、攔截器不依賴與servlet容器,過濾器依賴與servlet容器。 3、攔截器只能對ACTION請求起作用,而過濾器則可以對幾乎所有的請求起作用。 4、攔截器可以訪問ACTION上下文、值棧裡的物件,而過濾器不能訪問。 5、在ACTION的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次。 6、攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器裡注入一個service,可以呼叫業務邏輯。

  1. 定義攔截器
@Component		//宣告為springBoot的一個元件,但是並不能起作用,需要在springBoot的配置類中注入
public class TimeInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("TimeInterceptor 進入 Controller 某個方法之前");
		System.out.println("Controller Name:"+((HandlerMethod)handler).getBean().getClass().getName());
		System.out.println("Controller Method Name:"+((HandlerMethod)handler).getMethod().getName());
		request.setAttribute("startTime", new Date().getTime());
		
		/**
		 * boolean 值: 確定了攔截器其餘兩方法是否執行
		 */
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("TimeInterceptor 執行 Controller 某個方法時,方法丟擲異常將不進入此方法");
		long start = (long) request.getAttribute("startTime");
		System.out.println("TimeInterceptor 處理時長為:"+ (new Date().getTime() - start));

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("TimeInterceptor 完成 Controller 某個方法");
		long start = (long) request.getAttribute("startTime");
		System.out.println("TimeInterceptor 處理時長為:"+ (new Date().getTime() - start));

	}

}
  1. 注入攔截器
	//spring boot 1.0 -2.0版本
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

	@Autowired
	private TimeInterceptor timeInterceptor;

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(timeInterceptor);
	}
}

//spring boot 2.0以上版本
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {

    @Bean
    public MyWebMvcConfig getMyWebMvcConfig(){
        MyWebMvcConfig myWebMvcConfig = new MyWebMvcConfig() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("alogin");
                registry.addViewController("/login").setViewName("alogin");
                registry.addViewController("/main.html").setViewName("dashboard");
            }
            //註冊攔截器
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
                        .excludePathPatterns("/login","/","/user/login");
            }
        };
        return myWebMvcConfig;
    }