一、OncePerRequestFilter
OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行。
Springboot中javax.servlet.Filter原生接口的实现;而Spring的OncePerRequestFilter类实际上是一个实现了Filter接口的抽象类。spring对Filter进行了一些封装处理。 此方法是为了兼容不同的web container,也就是说并不是所有的container都入我们期望的只过滤一次,servlet版本不同,执行过程也不同,因此,为了兼容各种不同运行环境和版本,默认filter继承OncePerRequestFilter是一个比较稳妥的选择。
二、自定义过滤器
@Configuration
public class EncodeFilter extends OncePerRequestFilter {
private String encoding = "UTF-8";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
filterChain.doFilter(request, response);
}
}
OncePerRequestFilter,确保在一次请求中只通过一次filter。
优先级比拦截器高。
三、Spring boot filter 配置多个时,执行顺序
在 spring boot 配置Filter过滤器 中简单介绍了spring boot 中如何添加过滤器,有人问到如果配置多个怎么控制,先经过哪个过滤器,后经过哪个过滤器。在web.xml中,我们知道,执行顺序是谁在前边执行谁。
在spring boot中的FilterRegistrationBean注册过滤器的类中有个order属性,
private int order = Ordered.LOWEST_PRECEDENCE;
/**
* 配置过滤器
* @return
*/
@Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(sessionFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("sessionFilter");
registration.setOrder(Integer.MAX_VALUE);
return registration;
}
再有一个过滤器的话,可以设置成 registration.setOrder(Integer.MAX_VALUE - 1)
spring boot也提供了注解的方式:
/**
* 配置过滤器
* @return
*/
@Bean
@Order(Integer.MAX_VALUE)
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(sessionFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("sessionFilter");
return registration;
}