Servlet 過(guò)濾器屬于Servlet API,和Spring關(guān)系不大。除了使用過(guò)濾器包裝web請(qǐng)求,Spring MVC還提供HandlerInterceptor(攔截器)工具。根據(jù)文檔,HandlerInterceptor的功能跟過(guò)濾器類(lèi)似,但攔截器提供更精細(xì)的控制能力:在request被響應(yīng)之前、request被響應(yīng)之后、視圖渲染之前以及request全部結(jié)束之后。我們不能通過(guò)攔截器修改request內(nèi)容,但是可以通過(guò)拋出異常(或者返回false)來(lái)暫停request的執(zhí)行。
Spring MVC中常用的攔截器有:LocaleChangeInterceptor(用于國(guó)際化配置)和ThemeChangeInterceptor。我們也可以增加自己定義的攔截器,可以參考這篇文章中提供的demo
添加攔截器不僅是在WebConfiguration中定義bean,Spring Boot提供了基礎(chǔ)類(lèi)WebMvcConfigurerAdapter,我們項(xiàng)目中的WebConfiguration類(lèi)需要繼承這個(gè)類(lèi)。
修改后完整的WebConfiguration代碼如下:
package com.test.bookpub;
import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Bean public RemoteIpFilter remoteIpFilter() {
return new RemoteIpFilter();
}
@Bean public LocaleChangeInterceptor localeChangeInterceptor() {
return new LocaleChangeInterceptor();
}
@Override public void addInterceptors(InterceptorRegistry registry {
registry.addInterceptor(localeChangeInterceptor());
}
}
使用mvn spring-boot:run
運(yùn)行程序,然后通過(guò)httpie訪問(wèn)http://localhost:8080/books?locale=foo
,在終端看到如下錯(cuò)誤信息。
Servlet.service() for servlet [dispatcherServlet] in context with path []
threw exception [Request processing failed; nested exception is
java.lang.UnsupportedOperationException: Cannot change HTTP accept
header - use a different locale resolution strategy] with root cause
PS:這里發(fā)生錯(cuò)誤并不是因?yàn)槲覀冚斎氲膌ocale是錯(cuò)誤的,而是因?yàn)槟J(rèn)的locale修改策略不允許來(lái)自瀏覽器的請(qǐng)求修改。發(fā)生這樣的錯(cuò)誤說(shuō)明我們之前定義的攔截器起作用了。
在我們的示例項(xiàng)目中,覆蓋并重寫(xiě)了addInterceptors(InterceptorRegistory registory)方法,這是典型的回調(diào)函數(shù)——利用該函數(shù)的參數(shù)registry來(lái)添加自定義的攔截器。
在Spring Boot的自動(dòng)配置階段,Spring Boot會(huì)掃描所有WebMvcConfigurer的實(shí)例,并順序調(diào)用其中的回調(diào)函數(shù),這表示:如果我們想對(duì)配置信息做邏輯上的隔離,可以在Spring Boot項(xiàng)目中定義多個(gè)WebMvcConfigurer的實(shí)例。