gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 02:36:29 29 4
gpt4 key购买 nike

我正在使用 Spring boot v1.5.10 + Jersey v2.25.1,将 jersey 配置为过滤器以访问静态文件夹文件。我收到 HTTP 响应 400 Bad Request for a service 消费 MULTIPART_FORM_DATA .

将 Jersey 配置为过滤器的 Prop 。

spring.jersey.type=filter

如果我删除上述属性,即使用 Jersey 作为 Servlet,则服务正在运行,但我无法访问静态文件夹。

这是 Controller ,
@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/ (作品)

http://localhost:8080/hello.html (作品)

http://localhost:8080/save (不工作) - 使用 postman 。

spring.jersey.type=servlet
http://localhost:8080/ (作品)

http://localhost:8080/hello.html (不工作)

http://localhost:8080/save (作品)

Postman request

最佳答案

经过一番研究和查找相关问题1,似乎Spring的 HiddenHttpMethodFilter 读取输入流,对于过滤器链更下游的任何其他过滤器,它会将其留空。这就是我们在 Jersey 过滤器中收到错误请求的原因;因为实体流是空的。这是 Javadoc 中的注释

NOTE: This filter needs to run after multipart processing in case of a multipart POST request, due to its inherent need for checking a POST body parameter.



所以我们需要做的是配置Jersey过滤器在这个Spring filter2之前调用。基于 Spring Boot docs ,我们可以使用一个属性轻松配置此过滤器的顺序。
spring.jersey.filter.order

做一个 Github searchHiddenHttpMethodFilter 的 Spring Boot 存储库中,我们可以看到使用的子类 OrderedHiddenHttpMethodFilter ,其中顺序设置为 -10000 .所以我们希望将 Jersey 过滤器的顺序设置为小于(更高的优先级)。所以我们可以设置以下值
spring.jersey.filter.order=-100000

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

我们需要修复的另一件事是 Spring 的顺序 RequestContextFilter .这最初被配置为在 Jersey 过滤器之前被命令调用。当我们为 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

也可以看看
  • File upload along with other object in Jersey restful web service .这有一些关于如何在多部分请求中接受 JSON 作为正文部分的信息。


  • 脚注

    1. 需要关注的一些问题[ 1 , 2 ]
    2. 见 Change order of RequestContextFilter in the filter chain

    关于spring-boot - Spring Boot + Jersey 类型过滤器 - 服务消耗 MULTIPART_FORM_DATA 的错误请求 400,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50387638/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com