在Spring MVC框架中,`WebMvcConfigurationSupport`提供了一個基礎的配置類,用於設置控制器(Controller)、視圖解析器(ViewResolver)和其他一些常見的Spring MVC組件。其中,`addInterceptors()`方法是用來添加攔截器的。本篇文章將深入探討如何在Spring MVC中使用`WebMvcConfigurationSupport#addInterceptors()`方法和相關的配置選項。
什麼是 Spring MVC?
Spring MVC 是Spring Framework的一部分,它提供一個模型-視圖-控制器(MVC)架構來幫助開發人員構建web應用程序。Spring MVC允許開發者通過分離業務邏輯和表示層來簡化代碼結構,並且提供了強大的功能如數據綁定、驗證、國際化支持以及與其它Spring功能的集成。
WebMvcConfigurationSupport 的 addInterceptors() 方法概述
`WebMvcConfigurationSupport` 中的 `addInterceptors()` 方法是 Spring MVC 中的一個核心配置方法,它允許我們在 Spring MVC 中註冊自定義的攔截器。這個方法會返回一個 `HandlerInterceptorAdapter` 的實例列表,這些實例將在請求處理過程中被調用。我們可以通過繼承 `HandlerInterceptorAdapter` 或實現 `HandlerInterceptor` 接口來自定義我們的攔截器。
@Bean
public HandlerMappingCustomizer handlerMappingCustomizer() {
return new HandlerMappingCustomizer();
}
// HandlerMappingCustomizer.java
public class HandlerMappingCustomizer implements org.springframework.stereotype.Component {
private static final String INTERCEPTOR_ADVICE = "interceptorAdvice";
@Override
public void customizeHandlerMapping(org.springframework.web.servlet.config.annotation.WebMvcConfigurer configurer, org.springframework.context.ApplicationContext applicationContext) {
configurer.addInterceptors((handlers -> handlers.addInterceptor(new MyInterceptor()).order(Ordered.HIGHEST_PRECEDENCE)));
}
static class MyInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Before Request to the Controller");
return true; // 只有返回true時纔會繼續執行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("After Request from the Controller");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("Finally After Completing All Requests");
}
}
}
在上面的例子中,我們創建了一個名爲 `MyInterceptor` 的攔截器,它在請求進入控制器之前、之後以及整個請求完成之後分別調用了三個不同的方法。這樣我們就可以在這些關鍵點上進行日誌記錄、權限檢查或其他任何我們需要執行的邏輯操作。
Interceptor Ordering (攔截器順序)
每個攔截器可以有一個特定的優先級,這可以通過 `Order` 註解或者直接指定 `Ordered` 接口來實現。如果不指定優先級,那麼默認情況下它們將以註冊時的相反順序運行。這意味着如果兩個攔截器都在同一個配置文件中被註冊,而第一個註冊的將會最後執行。
你可以像下面這樣做來給某個 interceptor 指定 order:
@Component
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// do something before handle
return true; // allow proceed if not false or null
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
// do something after handle
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// do something when complete
}
// specify order using @Order annotation
@Order(value = Ordered.HIGHEST_PRECEDENCE + 10)
// alternatively implement Ordered interface and override compareTo method
// int compareTo(Object o);
}
多個攔截器的處理流程
當有多個攔截器需要處理同一個請求時,它們的處理順序取決於它們在 `addInterceptors()` 方法中的排列順序。例如,如果我們有兩個攔截器 `A` 和 `B`,且 `A` 在 `B` 的前面被添加到 `List` 中,那麼 `A` 將先於 `B` 被執行。
以下是如何在 `WebMvcConfigurationSupport` 中註冊多個攔截器的示例:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public HandlerInterceptor firstInterceptor() {
return new FirstInterceptor();
}
@Bean
public HandlerInterceptor secondInterceptor() {
return new SecondInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(firstInterceptor()).addPathPatterns("/path/**");
registry.addInterceptor(secondInterceptor()).excludePathPatterns("/excluded");
}
}
在這個例子中,`FirstInterceptor` 將被應用於所有以 “/path/” 爲前綴的 URL,而 `SecondInterceptor` 則會被排除掉 “/excluded” 路徑以外的所有其他路徑。請注意,這兩個攔截器之間沒有任何依賴關係,因此它們的執行順序並不重要。但是,如果你想要確保某些特定行爲(比如登錄驗證)總是在其他行爲之前發生,那麼就需要考慮這種依賴關係並在配置中反映出來。