Spring MVC 中的攔截器(Interceptor)相似於 Servlet 開發中的過濾器 Filter,它主要用於攔截用戶請求並做相應的處理,它也是 AOP 編程思想的體現,底層經過動態代理模式完成。html
攔截器有兩種實現方式: 1.實現 HandlerInterceptor 接口 2.繼承 HandlerInterceptorAdapter 抽象類(看源碼最底層也是經過 HandlerInterceptor 接口 實現)java
@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
1.日誌記錄:記錄請求信息的日誌,以便進行信息監控、信息統計、計算PV(Page View)等; 2.登陸鑑權:如登陸檢測,進入處理器檢測檢測是否登陸; 3.性能監控:檢測方法的執行時間; 4.其餘通用行爲。github
1.攔截器是基於java的反射機制的,而過濾器是基於函數回調。 2.攔截器不依賴於servlet容器,而過濾器依賴於servlet容器。 3.攔截器只能對Controller請求起做用,而過濾器則能夠對幾乎全部的請求起做用。 4.攔截器能夠訪問action上下文、值棧裏的對象,而過濾器不能訪問。 5.在Controller的生命週期中,攔截器能夠屢次被調用,而過濾器只能在容器初始化時被調用一次。 6.攔截器能夠獲取IOC容器中的各個bean,而過濾器不行。這點很重要,在攔截器裏注入一個service,能夠調用業務邏輯。spring
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");
}
}
複製代碼
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/* * 攔截器配置 */
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 註冊自定義攔截器,添加攔截路徑和排除攔截路徑
registry.addInterceptor(new Test1Interceptor()) // 添加攔截器
.addPathPatterns("/**") // 添加攔截路徑
.excludePathPatterns(// 添加排除攔截路徑
"/hello").order(0);//執行順序
super.addInterceptors(registry);
}
}
複製代碼
@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";
}
}
複製代碼
經過瀏覽器測試: http://127.0.0.1:8080/hello 結果:編程
這裏是Hello
複製代碼
http://127.0.0.1:8080/test1 、http://127.0.0.1:8080/test2 結果:瀏覽器
執行preHandle方法-->01
這裏是Test1
執行postHandle方法-->02
執行afterCompletion方法-->03
複製代碼
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");
}
}
複製代碼
@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);
}
}
複製代碼
@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";
}
}
複製代碼
經過瀏覽器測試: 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
複製代碼
經過示例,簡單的說多個攔截器執行流程就是先進後出。
@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;
}
複製代碼
未傳token:
執行Test1Interceptor preHandle方法-->01
複製代碼
傳token:
執行Test1Interceptor preHandle方法-->01
頁碼:1
頁碼大小:10
執行Test1Interceptor postHandle方法-->02
執行Test1Interceptor afterCompletion方法-->03
複製代碼
非特殊說明,本文版權歸 朝霧輕寒 全部,轉載請註明出處.
原文標題:Spring Boot 2.X(九):Spring MVC - 攔截器(Interceptor)
原文地址: https://www.zwqh.top/article/info/18
若是文章對您有幫助,請掃碼關注下個人公衆號,文章持續更新中...