如何在Spring Boot应用程序中定义Servlet过滤器的执行顺序

Man*_*anu 36 spring-boot

我试图在我的spring启动应用程序中设置2个过滤器的执行顺序,它们具有相同的url映射.我尝试在我的主Application类中使用2个过滤器注册bean,如下所示,但是没有用.我希望authorizationFilter先被击中validationFilter.但是,只有validationFilter在两者都配置好的时候它总是会命中.如果我发表评论validationFilter,它就会命中authorizationFilter.

@Bean
public FilterRegistrationBean authorizationFilter(){
    FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
    filterRegBean.setFilter(authorizationFilter);
    List<String> urlPatterns = new ArrayList<String>();
    urlPatterns.add("/v1/*");
    filterRegBean.setUrlPatterns(urlPatterns);
    return filterRegBean;
}

@Bean
public FilterRegistrationBean validationFilter(){
    FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
    filterRegBean.setFilter(validationFilter);
    List<String> urlPatterns = new ArrayList<String>();
    urlPatterns.add("/v1/*");
    filterRegBean.setUrlPatterns(urlPatterns);
    return filterRegBean;
}
Run Code Online (Sandbox Code Playgroud)

我也试过web.xml将可执行jar 引入并转换为war文件.

<web-app>   
<filter>
    <filter-name>authorizationFilter</filter-name>
    <filter-class>com.security.filter.AuthorizationFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>authorizationFilter</filter-name>
    <url-pattern>/v1/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>validationFilter</filter-name>
    <filter-class>com.security.validation.ValidationFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>validationFilter</filter-name>
    <url-pattern>/v1/*</url-pattern>
</filter-mapping>
</web-app>
Run Code Online (Sandbox Code Playgroud)

但是应用程序似乎没有识别web.xml,因为它只使用上面的配置命中验证过滤器.我很感激解决这个问题的任何意见.谢谢

小智 47

setOrder(int) 方法完成这项工作.

下面是一个例子

@Configuration
@EnableAutoConfiguration
@EnableWebMvc
@ComponentScan
public class Application {

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        SecurityFilter securityFilter = new SecurityFilter();
        registrationBean.setFilter(securityFilter);
        registrationBean.setOrder(2);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean contextFilterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        RequestContextFilter contextFilter = new RequestContextFilter();
        registrationBean.setFilter(contextFilter);
        registrationBean.setOrder(1);
        return registrationBean;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @AmitGupta 您可以在过滤器类的定义中添加 Order 注释。如:@Component @Order(1) public class ApiCrossDomainFilter extends GenericFilterBean {} (2认同)
  • @AmitKumarGupta Order 可以是 Integer.MIN_VALUE 和 Integer.MAX_VALUE 之间的任意数字,如 Ordered 接口中定义。Integer.MAX_VALUE 基本上意味着它将具有最低优先级,而 MAX_VALUE -1 具有比前一个更高的优先级。值越高,优先级越低。它基本上是相同的,但如果示例不起作用,那么可能有一些其他过滤器正在较早执行,并且该过程不会到达您的过滤器。 (2认同)

Dav*_*yer 17

Spring Boot 在将它们应用到servlet上下文之前对您的FilterRegistrationBean使用AnnotationAwareOrderComparator进行排序.在RegistrationBean当前不Ordered那么有没有办法通过调用一个方法来设置的顺序,但可以解决通过创建子类,并加入@Order他们.我认为创建基类Ordered并提供setter在框架中可能是一件有用的事情(如果你同意的话,在github上打开一个问题).

更新:Ordered在1.0.x中添加.