首页 > 解决方案 > 过滤器链中 RequestContextFilter 的更改顺序

问题描述

我正在将 Jersey 与 Spring Boot 一起使用,并且需要将 Jersey 配置为作为 Servlet 过滤器运行。问题在于,使用 Multipart 时,我们会为所有请求收到 400 Bad Request。进一步的研究表明这HiddenHttpMethodFilter是问题所在,因为它读取了请求参数,导致请求流被读取,没有给 Jersey 留下任何东西。

为了解决这个问题,我正在执行 Javadoc 中所述的HiddenHttpMethodFilter操作:将 Jersey 过滤器配置为在此过滤器之前运行。

注意:在多部分 POST 请求的情况下,此过滤器需要在多部分处理之后运行,因为它固有地需要检查 POST 正文参数。

要配置 Jersey 过滤器的顺序,我使用 Spring Boot 属性

spring.jersey.filter.order=-100000

这行得通。以下是过滤器链顺序的前后日志

Mapping filter: 'characterEncodingFilter' to: [/*]
Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
Mapping filter: 'httpPutFormContentFilter' to: [/*]
Mapping filter: 'requestContextFilter' to: [/*]
Mapping filter: 'jerseyFilter' to urls: [/*]

Mapping filter: 'characterEncodingFilter' to: [/*]
Mapping filter: 'jerseyFilter' to urls: [/*]
Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
Mapping filter: 'httpPutFormContentFilter' to: [/*]
Mapping filter: 'requestContextFilter' to: [/*]

所以你可以看到它jerseyFilter被正确地重新排序。但requestContextFilter需要在jerseyFilter. 我正在寻找 的来源JerseyAutoConfiguration,它显示requestContextFilter顺序设置为-1Jersey 过滤器配置。但这似乎不是正在发生的事情

@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean<RequestContextFilter> requestContextFilter() {
    FilterRegistrationBean<RequestContextFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(new RequestContextFilter());
    registration.setOrder(this.jersey.getFilter().getOrder() - 1);
    registration.setName("requestContextFilter");
    return registration;
}

在进一步调查中,我发现上面列出的所有过滤器都有一个Ordered子类,我认为这是正在注册的。例如,有一个OrderedRequestContextFilter,其顺序设置为-105。如果我设置了DEBUG日志记录,我可以看到情况仍然如此,即使我设置了 Jersey 过滤器顺序属性

'characterEncodingFilter'; order=-2147483648,
'hiddenHttpMethodFilter'; order=-10000,
'httpPutFormContentFilter'; order=-9900,
'requestContextFilter'; order=-105,

所以基本上,我只是想弄清楚改变过滤器顺序的正确方法是什么RequestContextFilter,以便它在 Jersey 过滤器之前执行。

标签: javaspringspring-boot

解决方案


所以在 中WebMvcAutoConfiguration,我发现

@Bean
@ConditionalOnMissingBean({ RequestContextListener.class,
        RequestContextFilter.class })
public static RequestContextFilter requestContextFilter() {
    return new OrderedRequestContextFilter();
}

所以我尝试添加相同的 bean 并在OrderedRequestContextFilter.

@Bean
public RequestContextFilter requestContextFilter() {
    OrderedRequestContextFilter filter = new OrderedRequestContextFilter();
    filter.setOrder(-100001);
    return filter;
}

这行得通,我得到了我想要的结果;RequestContextFilter是在 Jersey 过滤器之前订购的。

Mapping filter: 'characterEncodingFilter' to: [/*]
Mapping filter: 'requestContextFilter' to: [/*]
Mapping filter: 'jerseyFilter' to urls: [/*]
Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
Mapping filter: 'httpPutFormContentFilter' to: [/*]

推荐阅读