我使用Spring boot v1.5.10 + Jersey v2.25.1,将jersey配置为过滤器来访问静态文件夹文件。我收到的HTTP响应400 Bad Request for service MULTIPART_FORM_DATA
。
道具将泽西岛配置为过滤器。
spring.jersey.type=filter
如果删除上面的属性,即使用Jersey作为Servlet,该服务正在运行,但我无法访问静态文件夹。
这是控制器,
@POST
@Path("/save")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public ResponseBean save(
@FormDataParam("fileToUpload") InputStream file,
@FormDataParam("fileToUpload") FormDataContentDisposition fileDisposition,
@FormDataParam("fromData") FormDataDto data) {
// stuff
}
修改
GitHub链接https://github.com/sundarabalajijk/boot-jersey
启动应用时,spring.jersey.type=filter
http://localhost:8080/hello.html(有效)
http://localhost:8080/save(不工作) - 使用过邮差。
spring.jersey.type=servlet
http://localhost:8080/hello.html(不工作)
答案 0 :(得分:6)
经过一些研究和发现相关问题 1 后,Spring HiddenHttpMethodFilter
似乎读取了输入流,这使得它对于过滤器链下游的任何其他过滤器都是空的。这就是为什么我们在Jersey过滤器中获得错误请求的原因;因为实体流是空的。以下是Javadoc的说明
注意:由于需要检查POST正文参数,因此在多部分POST请求的情况下,此过滤器需要在多部分处理之后运行。
所以我们需要做的是配置在此Spring过滤器 2 之前调用的Jersey过滤器。基于Spring Boot docs,我们可以使用一个属性来轻松配置此过滤器的顺序。
spring.jersey.filter.order
在HiddenHttpMethodFilter
的Spring Boot repo中执行Github search,我们可以看到使用的子类OrderedHiddenHttpMethodFilter,其中订单设置为-10000
。因此,我们希望将Jersey过滤器的顺序设置为小于该值(更高的优先级)。所以我们可以设置以下值
spring.jersey.filter.order=-100000
如果你现在测试它,它现在应该可以工作。
我们需要解决的另一件事是Spring RequestContextFilter
的顺序。这最初配置为在Jersey过滤器之前被命令调用。当我们为泽西过滤器设置上面的订单配置时,RequestContextFilter
保持原来的位置。所以我们需要改变这一点。我们只需添加一个bean来覆盖原始bean并设置顺序即可。
@Bean
public RequestContextFilter requestContextFilter() {
OrderedRequestContextFilter filter = new OrderedRequestContextFilter();
filter.setOrder(-100001);
return filter;
}
现在,如果我们在启动时检查日志,我们应该看到我们想要的文件管理器订单。
Mapping filter: 'characterEncodingFilter' to: [/*]
Mapping filter: 'requestContextFilter' to: [/*]
Mapping filter: 'jerseyFilter' to urls: [/*]
Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
Mapping filter: 'httpPutFormContentFilter' to: [/*]
在您的情况下需要将Jersey配置为过滤器的原因是静态内容。如果您没有为Jersey应用程序配置根路径,则默认为/*
,这将占用所有请求,包括静态内容的请求。因此,当对静态内容发出请求时,Jersey会抛出404错误。我们将Jersey配置为过滤器并告诉它转发它无法找到的请求。
如果我们只是为Jersey配置根路径,那么我们就不需要担心静态内容的这个问题了,我们可以默认将Jersey配置为servlet。
要更改Jersey应用的基本路径,我们可以将@ApplicatuonPath
注释添加到ResourceConfig
或我们可以使用属性spring.jersey.application-path
@Component
@ApplicationPath("/api")
public class JerseyConfig extends ResourceConfig {
...
}
或在application.properties
spring.jersey.application-path=/api
<子> 1。要查看[1,2] 的一些问题 <子> 2。请参阅Change order of RequestContextFilter in the filter chain