Spring Boot + Jersey类型过滤器-对服务的错误请求400消耗MULTIPART_FORM_DATA [英] Spring Boot + Jersey type filter - Bad request 400 for service Consumes MULTIPART_FORM_DATA
问题描述
我使用的是Spring boot v1.5.10 + Jersey v2.25.1,已将jersey配置为用于访问静态文件夹文件的过滤器.我收到使用MULTIPART_FORM_DATA
的服务的HTTP响应400错误请求.
道具将Jersey配置为过滤器.
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 (无效)
http://localhost:8080/save (有效)
经过一些研究并发现了相关问题 1 ,看来Spring是 Spring Boot文档 ,我们可以使用一个属性轻松配置此过滤器的顺序.
spring.jersey.filter.order
执行在Spring Boot存储库中搜索Github 以查找
在这种情况下,您需要将Jersey配置为过滤器的原因是因为其内容是静态的.如果未配置Jersey应用程序的根路径,则默认为 如果我们只是为Jersey配置根路径,那么我们就不必担心静态内容的问题,并且我们可以默认将Jersey配置为servlet. 要更改Jersey应用程序的基本路径,我们可以在 或您的
1.需要注意的一些问题[ 1 ,更改过滤器链中RequestContextFilter的顺序 I'm using Spring boot v1.5.10 + Jersey v2.25.1, configured jersey as filter to access static folder files. I'm getting HTTP response 400 Bad Request for a service consuming Props to configure Jersey as filter. If I remove above property i.e., using Jersey as Servlet, the service is working, but I'm not able to access static folder. Here is the controller, EDIT: GitHub link https://github.com/sundarabalajijk/boot-jersey When you start the app, http://localhost:8080/ (works) http://localhost:8080/hello.html (works) http://localhost:8080/save (not working) - used postman. When http://localhost:8080/ (works) http://localhost:8080/hello.html (not working) http://localhost:8080/save (works) After some research and finding related issues1, it seems that Spring's 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. So what we need to do is configure the Jersey filter to be called before this Spring filter2. Based on the Spring Boot docs, there is a property we can use to easily configure the order of this filter. Doing a Github search in the Spring Boot repo for the If you test it now, it should now work. One more thing we need to fix is the order of the Spring Now if we check the logs on startup, we should see the filer ordering we want.
The reason you need to configure Jersey as a filter in your case is because of the static content. If you don't configure the root path for the Jersey app, then it defaults to If we were to just configure the root path for Jersey, then we would not need to worry about this problem with the static content, and we would be able to just leave Jersey configured as a servlet by default. To change the base path for the Jersey app, we can either add the or in your
1. Some issues to look at [ 1, 2 ] 这篇关于Spring Boot + Jersey类型过滤器-对服务的错误请求400消耗MULTIPART_FORM_DATA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!HiddenHttpMethodFilter
,我们可以看到所使用的子类 Mapping filter: 'characterEncodingFilter' to: [/*]
Mapping filter: 'requestContextFilter' to: [/*]
Mapping filter: 'jerseyFilter' to urls: [/*]
Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
Mapping filter: 'httpPutFormContentFilter' to: [/*]
在旁边
/*
,它将占用所有请求,包括那些包含在静态内容中的请求.因此,当请求静态内容时,Jersey将抛出404错误.我们将Jersey配置为过滤器,并告诉它转发找不到的请求.ResourceConfig
中添加@ApplicatuonPath
批注,也可以使用属性spring.jersey.application-path
@Component
@ApplicationPath("/api")
public class JerseyConfig extends ResourceConfig {
...
}
application.properties
spring.jersey.application-path=/api
另请参见
脚语
MULTIPART_FORM_DATA
.spring.jersey.type=filter
@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
}
spring.jersey.type=filter
spring.jersey.type=servlet
HiddenHttpMethodFilter
reads the input stream, which leaves it empty for any other filters further down the filter chain. This is why we are getting a Bad Request in the Jersey filter; because the entity stream is empty. Here is the note from the Javadoc
spring.jersey.filter.order
HiddenHttpMethodFilter
, we can see the subclass that is used OrderedHiddenHttpMethodFilter, where the order is set to -10000
. So we want to set the order of our Jersey filter to less than that (higher precedence). So we can set the following valuespring.jersey.filter.order=-100000
RequestContextFilter
. This is originally configured to be ordered to be called right before the Jersey filter. When we set the order configuration above for the Jersey filter, the RequestContextFilter
stays where it was originally at. So we need to change this. We can do this just by adding a bean to override the original one and set the order.@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: [/*]
Aside
/*
, which will hog up all requests, included those to the static content. So Jersey will throw 404 errors when requests are made for the static content. We configure Jersey as a filter and tell it to forward request that it cannot find.@ApplicatuonPath
annotation to our ResourceConfig
or we can use the property spring.jersey.application-path
@Component
@ApplicationPath("/api")
public class JerseyConfig extends ResourceConfig {
...
}
application.properties
spring.jersey.application-path=/api
See also
Footnotes
2. See Change order of RequestContextFilter in the filter chain