Servlet 过滤器属于Servlet API,和Spring关系不大。除了使用过滤器包装web请求,Spring MVC还提供HandlerInterceptor(拦截器)工具。根据文档,HandlerInterceptor的功能跟过滤器类似,但拦截器提供更精细的控制能力:在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。我们不能通过拦截器修改request内容,但是可以通过抛出异常(或者返回false)来暂停request的执行。
Spring MVC中常用的拦截器有:LocaleChangeInterceptor(用于国际化配置)和ThemeChangeInterceptor。我们也可以增加自己定义的拦截器,可以参考这篇文章中提供的demo
How Do
添加拦截器不仅是在WebConfiguration中定义bean,Spring Boot提供了基础类WebMvcConfigurerAdapter,我们项目中的WebConfiguration类需要继承这个类。
- 继承WebMvcConfigurerAdapter;
- 为LocaleChangeInterceptor添加@Bean定义,这仅仅是定义了一个interceptor spring bean,但是Spring boot不会自动将它加入到调用链中。
- 拦截器需要手动加入调用链。
修改后完整的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
运行程序,然后通过httpie访问http://localhost:8080/books?locale=foo
,在终端看到如下错误信息。