Spring Boot + Jersey类型过滤器-对服务的错误请求400消耗MULTIPART_FORM_DATA

Sun*_*J K 4 file-upload jax-rs servlet-filters jersey-2.0 spring-boot

我正在使用Spring Boot v1.5.10 + Jersey v2.25.1,将jersey配置为过滤器来访问静态文件夹文件。我收到HTTP响应400错误的服务消耗请求MULTIPART_FORM_DATA

提议将Jersey配置为过滤器。

spring.jersey.type=filter
Run Code Online (Sandbox Code Playgroud)

如果我删除了上述属性,即使用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
}
Run Code Online (Sandbox Code Playgroud)

编辑:

GitHub链接https://github.com/sundarabalajijk/boot-jersey

启动应用程序时, spring.jersey.type=filter

http:// localhost:8080 /(有效)

http:// localhost:8080 / hello.html(有效)

http:// localhost:8080 / save(不起作用)-使用的邮递员。

什么时候 spring.jersey.type=servlet

http:// localhost:8080 /(有效)

http:// localhost:8080 / hello.html(无效)

http:// localhost:8080 / save(有效)

邮递员要求

Pau*_*tha 9

经过一些研究并找到了相关问题,1似乎Spring HiddenHttpMethodFilter读取了输入流,这使它在过滤器链中的其他任何过滤器中都为空。这就是为什么我们在Jersey过滤器中收到错误请求的原因;因为实体流为空。这是Javadoc的注释

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

因此,我们需要做的是将Jersey过滤器配置为在此Spring过滤器2之前调用。根据Spring Boot docs,有一个属性可用于轻松配置此过滤器的顺序。

spring.jersey.filter.order
Run Code Online (Sandbox Code Playgroud)

做一个Github上搜索在春季启动回购的HiddenHttpMethodFilter,我们可以看到所使用的子类OrderedHiddenHttpMethodFilter,其中顺序设置为-10000。因此,我们希望将Jersey过滤器的顺序设置为小于该顺序(更高的优先级)。因此我们可以设置以下值

spring.jersey.filter.order=-100000
Run Code Online (Sandbox Code Playgroud)

如果现在进行测试,它现在应该可以工作。

我们需要修复的另一件事是Spring的顺序RequestContextFilter。最初将其配置为在Jersey过滤器之前被命令调用。当我们在上方为“ Jersey”过滤器设置了订单配置时,RequestContextFilter停留时间将保持在原来的状态。因此,我们需要对此进行更改。我们可以通过添加一个bean来覆盖原始的bean并设置顺序来做到这一点。

@Bean
public RequestContextFilter requestContextFilter() {
    OrderedRequestContextFilter filter = new OrderedRequestContextFilter();
    filter.setOrder(-100001);
    return filter;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们在启动时检查日志,我们应该会看到所需的文件管理器顺序。

spring.jersey.filter.order
Run Code Online (Sandbox Code Playgroud)

在旁边

在这种情况下,您需要将Jersey配置为过滤器的原因是由于静态内容。如果您未配置Jersey应用程序的根路径,则默认为/*,它将占用所有请求,包括静态内容在内的所有请求。因此,当请求静态内容时,Jersey将抛出404错误。我们将Jersey配置为过滤器,并告诉它转发找不到的请求。

如果我们仅配置Jersey的根路径,那么我们就不必担心静态内容的问题,默认情况下我们就可以将Jersey配置为servlet。

要更改Jersey应用程序的基本路径,我们可以将@ApplicatuonPath注释添加到我们的应用程序中,也ResourceConfig可以使用属性spring.jersey.application-path

@Component
@ApplicationPath("/api")
public class JerseyConfig extends ResourceConfig {
    ...
}
Run Code Online (Sandbox Code Playgroud)

或在你的 application.properties

spring.jersey.application-path=/api
Run Code Online (Sandbox Code Playgroud)

也可以看看


脚注

1.一些问题看[ 12 ]
2.见RequestContextFilter两个的变化顺序在过滤器链