請求 → DispatcherServlet → HandlerMapping (決定 Controller) → Controller → ViewResolver → 視圖。HandlerMapping 是植入攔截器的第一個天然切點,此外可實現 WebRequestInterceptor 接口。
三個核心方法,構成「前-中-後」完整攔截鏈:
false:中斷鏈,後續攔截器與 Controller 均不執行。true:繼續下一個攔截器或 Controller。ModelAndView:增刪改模型數據、切換視圖。preHandle=true 的攔截器。ex 做異常後處理。public class SpringMVCInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
// 返回 false 可攔截請求
return true;
}
@Override
public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView mv) {
// mv.addObject("key", "value"); 修改模型
}
@Override
public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) {
// 清理資源
}
}
基於 Spring 封裝的 WebRequest (統一 HttpServletRequest/PortletRequest),三方法參數一致,攔截語義類似但無阻斷能力:
WebRequest 屬性,三作用域:SCOPE_REQUEST (0) 僅請求、SCOPE_SESSION (1) 會話、SCOPE_GLOBAL_SESSION (2) 全局會話。ModelMap 改變渲染數據。preHandle 準備的資源。Exception 為異常對象 (已被處理則為 null)。public class AllInterceptor implements WebRequestInterceptor {
@Override public void preHandle(WebRequest req) {
req.setAttribute("request", "val", WebRequest.SCOPE_REQUEST);
req.setAttribute("session", "val", WebRequest.SCOPE_SESSION);
req.setAttribute("global", "val", WebRequest.SCOPE_GLOBAL_SESSION);
}
@Override public void postHandle(WebRequest req, ModelMap map) {
map.put("name3", "value3"); // 新增模型
map.put("name1", "newVal"); // 覆蓋模型
}
@Override public void afterCompletion(WebRequest req, Exception ex) {
// ex 為 null 表示無未處理異常
}
}
Spring 提供的抽象適配器類,默認方法空實現,僅覆寫需要的方法,代碼更乾淨。
<mvc:interceptors>
<!-- 全局攔截:直接定義 bean,攔截所有請求 -->
<bean class="com.host.app.web.interceptor.AllInterceptor"/>
<!-- 路徑精確攔截 -->
<mvc:interceptor>
<mvc:mapping path="/test/number.do"/>
<bean class="com.host.app.web.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
preHandle 正序執行;postHandle、afterCompletion 逆序執行。preHandle 返回 false 立即中斷,對應 afterCompletion 不執行。| 維度 | HandlerInterceptor | WebRequestInterceptor |
|---|---|---|
| 阻斷請求 | 支持 (preHandle 返回 false) | 不支持 |
| 作用域屬性 | 手動操作 request/session | 內置 SCOPE_* 常量 |
| Model 操作 | ModelAndView (功能豐富) | ModelMap (輕量) |
| 適用場景 | 登錄驗證、權限、API 簽名 | 跨平台資源綁定、Session 管理 |
HandlerInterceptorAdapter 減少樣板代碼。preHandle 中避免耗時操作,影響吞吐。HandlerExceptionResolver,afterCompletion 僅做清理。