我使用Jersey和Spring Boot,需要配置Jersey作为Servlet过滤器运行。这样做的问题是,使用Multipart,我们会收到所有请求的400 Bad Request。进一步的研究表明,HiddenHttpMethodFilter
是问题所在,因为它读取了请求参数,导致请求流被读取,没有留下泽西的任何内容。
要解决此问题,我正在执行HiddenHttpMethodFilter
的Javadoc中所述的内容:将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
顺序设置为泽西过滤器配置的-1
。但这似乎并不是正在发生的事情
@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
日志记录,我可以看到情况仍然如此,即使我设置了泽西过滤器顺序属性
'characterEncodingFilter'; order=-2147483648,
'hiddenHttpMethodFilter'; order=-10000,
'httpPutFormContentFilter'; order=-9900,
'requestContextFilter'; order=-105,
基本上,我只想弄清楚更改RequestContextFilter
的过滤器顺序的正确方法是什么,以便它在Jersey过滤器之前执行。
答案 0 :(得分:1)
所以在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
。
Mapping filter: 'characterEncodingFilter' to: [/*]
Mapping filter: 'requestContextFilter' to: [/*]
Mapping filter: 'jerseyFilter' to urls: [/*]
Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
Mapping filter: 'httpPutFormContentFilter' to: [/*]