Spring Boot 2.X(九):Spring MVC - 攔截器(Interceptor)

攔截器

1.簡介

Spring MVC 中的攔截器(Interceptor)相似於 Servlet 開發中的過濾器 Filter,它主要用於攔截用戶請求並做相應的處理,它也是 AOP 編程思想的體現,底層經過動態代理模式完成。html

2.定義實現類

攔截器有兩種實現方式: 1.實現 HandlerInterceptor 接口 2.繼承 HandlerInterceptorAdapter 抽象類(看源碼最底層也是經過 HandlerInterceptor 接口 實現)java

3.HandlerInterceptor方法介紹

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		
        //進行邏輯判斷,若是ok就返回true,不行就返回false,返回false就不會處理請求
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
	}
複製代碼

preHandle:在業務處理器處理請求以前被調用。預處理,能夠進行編碼、安全控制、權限校驗等處理; postHandle:在業務處理器處理請求執行完成後,生成視圖以前執行。 afterCompletion:在 DispatcherServlet 徹底處理完請求後被調用,可用於清理資源等。git

4.應用場景

1.日誌記錄:記錄請求信息的日誌,以便進行信息監控、信息統計、計算PV(Page View)等; 2.登陸鑑權:如登陸檢測,進入處理器檢測檢測是否登陸; 3.性能監控:檢測方法的執行時間; 4.其餘通用行爲。github

5.與 Filter 過濾器的區別

1.攔截器是基於java的反射機制的,而過濾器是基於函數回調。 2.攔截器不依賴於servlet容器,而過濾器依賴於servlet容器。 3.攔截器只能對Controller請求起做用,而過濾器則能夠對幾乎全部的請求起做用。 4.攔截器能夠訪問action上下文、值棧裏的對象,而過濾器不能訪問。 5.在Controller的生命週期中,攔截器能夠屢次被調用,而過濾器只能在容器初始化時被調用一次。 6.攔截器能夠獲取IOC容器中的各個bean,而過濾器不行。這點很重要,在攔截器裏注入一個service,能夠調用業務邏輯。spring

具體實現

單個攔截器

1.新建攔截器

public class Test1Interceptor implements HandlerInterceptor{

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("執行preHandle方法-->01");
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("執行postHandle方法-->02");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println("執行afterCompletion方法-->03");
	}
}
複製代碼

2.配置攔截器

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
	/* * 攔截器配置 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 註冊自定義攔截器,添加攔截路徑和排除攔截路徑
		registry.addInterceptor(new Test1Interceptor()) // 添加攔截器
				.addPathPatterns("/**") // 添加攔截路徑
				.excludePathPatterns(// 添加排除攔截路徑
						"/hello").order(0);//執行順序
		super.addInterceptors(registry);
	}

}
複製代碼

3.測試攔截器

@RestController
public class TestController {

	@RequestMapping("/hello")
	public String getHello() {
		System.out.println("這裏是Hello");
		return "hello world";
	}
	
	
	@RequestMapping("/test1")
	public String getTest1() {
		System.out.println("這裏是Test1");
		return "test1 content";
	}
	
	@RequestMapping("/test2")
	public String getTest2() {
		System.out.println("這裏是Test2");
		return "test2 content";
	}
}
複製代碼

4.單個攔截器的執行流程

經過瀏覽器測試: http://127.0.0.1:8080/hello 結果:編程

這裏是Hello
複製代碼

http://127.0.0.1:8080/test1http://127.0.0.1:8080/test2 結果:瀏覽器

執行preHandle方法-->01
這裏是Test1
執行postHandle方法-->02
執行afterCompletion方法-->03
複製代碼

多個攔截器

1.新建兩個攔截器

Test1Interceptor安全

public class Test1Interceptor implements HandlerInterceptor{
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("執行Test1Interceptor preHandle方法-->01");
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("執行Test1Interceptor postHandle方法-->02");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println("執行Test1Interceptor afterCompletion方法-->03");
	}
}
複製代碼

Test2Interceptorbash

public class Test2Interceptor extends HandlerInterceptorAdapter{


	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("執行Test2Interceptor preHandle方法-->01");
		return true;
	}
	
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("執行Test2Interceptor postHandle方法-->02");
	}

	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println("執行Test2Interceptor afterCompletion方法-->03");
	}
}

複製代碼

2.配置攔截器

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
	/* * 攔截器配置 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 註冊自定義攔截器,添加攔截路徑和排除攔截路徑
		registry.addInterceptor(new Test1Interceptor()) // 添加攔截器1
				.addPathPatterns("/**") // 添加攔截路徑
				.excludePathPatterns(// 添加排除攔截路徑
						"/hello")
				.order(0);
		registry.addInterceptor(new Test2Interceptor()) // 添加攔截器2
				.addPathPatterns("/**") // 添加攔截路徑
				.excludePathPatterns(// 添加排除攔截路徑
						"/test1")
				.order(1);
		super.addInterceptors(registry);
	}

}
複製代碼

3.測試攔截器

@RestController
public class TestController {

	@RequestMapping("/hello")
	public String getHello() {
		System.out.println("這裏是Hello");
		return "hello world";
	}
	
	
	@RequestMapping("/test1")
	public String getTest1() {
		System.out.println("這裏是Test1");
		return "test1 content";
	}
	
	@RequestMapping("/test2")
	public String getTest2() {
		System.out.println("這裏是Test2");
		return "test2 content";
	}
}
複製代碼

4.多個攔截器的執行流程

經過瀏覽器測試: http://127.0.0.1:8080/test2 結果:app

執行Test1Interceptor preHandle方法-->01
執行Test2Interceptor preHandle方法-->01
這裏是Test2
執行Test2Interceptor postHandle方法-->02
執行Test1Interceptor postHandle方法-->02
執行Test2Interceptor afterCompletion方法-->03
執行Test1Interceptor afterCompletion方法-->03
複製代碼

經過示例,簡單的說多個攔截器執行流程就是先進後出

簡單的 token 判斷示例

1.攔截器

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("執行Test1Interceptor preHandle方法-->01");
		
		String token = request.getParameter("token");
		if (StringUtils.isEmpty(token)) {			
			response.setContentType("text/html");
			response.setCharacterEncoding("UTF-8");
			response.getWriter().println("token不存在");
			return false;
		}
		return true;
	}
複製代碼

2.測試及結果

未傳token:

執行Test1Interceptor preHandle方法-->01
複製代碼

傳token:

執行Test1Interceptor preHandle方法-->01
頁碼:1
頁碼大小:10
執行Test1Interceptor postHandle方法-->02
執行Test1Interceptor afterCompletion方法-->03
複製代碼

示例代碼

github

碼雲

非特殊說明,本文版權歸 朝霧輕寒 全部,轉載請註明出處.

原文標題:Spring Boot 2.X(九):Spring MVC - 攔截器(Interceptor)

原文地址: https://www.zwqh.top/article/info/18

若是文章對您有幫助,請掃碼關注下個人公衆號,文章持續更新中...

相關文章
相關標籤/搜索