聲明:所有的代碼基於SpringBoot 2.0.3版本
HandlerInterceptor簡介
HandlerInterceptor是一個允許自定義處理鏈的工作流接口。應用程序可以爲某些處理程序註冊任意數量的現有或自定義攔截器,無需修改現有攔截器的實現即可增加常見的預處理動作。在適當的HandlerAdapter觸發處理程序本身的執行之前調用HandlerInterceptor。該機制可用於很多領域的預處理工作,例如, 授權檢查,通用處理流程(區域設置或主題更改)。 攔截器的其主要目的是允許分解重複的處理代碼。
在異步處理場景中,攔截器可以在單獨的線程中執行,主線程退出可能不會調用postHandle和afterCompletion方法。當併發處理程序執行完成後,請求將再次被分發以繼續呈現模型,並再次調用所有攔截的方法。關於異步攔截器可以參考AsyncHandlerInterceptor。
HandlerInterceptor接口方法
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception
攔截handler的執行,在HandlerMapping確定合適的handler之後,調用handler之前調用該方法。DispatcherServlet在包含多個攔截器的執行鏈中處理一個handler,並在執行鏈的結尾執行handler自身。通過該方法,每個攔截器可以決定中止執行鏈,通常是發送HTTP錯誤或返回自定義響應。
參數
request - 當前HTTP請求
response - 當前HTTP響應
handler - 選擇的handler
返回值
true - 執行鏈可以執行下一個攔截器或handler本身。
false - 攔截器已經處理了相應。
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception
攔截handler的執行,在HandlerAdapter調用handler之後,DispatcherServlet呈現視圖之前調用該方法。可以通過給定的ModelAndView向視圖增加其他模型對象。DispatcherServlet在包含多個攔截器的執行鏈中處理一個handler,並在執行鏈的結尾執行handler自身。使用該方法,每個攔截器都可以對操作後處理,實現按照處理鏈逆序執行。
參數
request - 當前HTTP請求
response - 當前HTTP響應
handler - 異步執行器
modelAndView - 處理返回值的模型視圖
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception
在請求處理完成而且preHandle執行完成並返回true的條件下才調用該方法,使用該方法可以進行合理的資源清理。
參數
request - 當前HTTP請求
response - 當前HTTP響應
handler - 異步執行器
ex - 當前攔截器拋出的異常
SpringBoot中自定義Interceptor
自定義Interceptor
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String heanderName = headerNames.nextElement();
System.out.println(heanderName);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
System.out.println("post handle finish");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
System.out.println("complete handle request");
}
}
註冊Interceptor
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CustomConfigure implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/user");
}
}
將自定義的Interceptor註冊後啓動SpringBoot應用,訪問/user即可看到攔截器可以正常工作。