Spring 具有多部分的PUT请求被Zuul/DispatcherServlet损坏(多部分数据被删除)
我们正在使用Zuul将请求转发到内部微服务。内部服务有两个端点(一个PUT端点和一个POST端点)。我们发现,多部分请求在到达内部PUT端点之前就已损坏 多部分数据似乎已从请求中删除。这似乎只适用于PUT请求,因为POST可以完美地工作 如果我们使用cURL直接命中内部PUT端点,那么请求将得到正确处理。相应的cURL命令和请求主体如下所示:Spring 具有多部分的PUT请求被Zuul/DispatcherServlet损坏(多部分数据被删除),spring,spring-boot,multipart,netflix-zuul,spring-cloud-netflix,Spring,Spring Boot,Multipart,Netflix Zuul,Spring Cloud Netflix,我们正在使用Zuul将请求转发到内部微服务。内部服务有两个端点(一个PUT端点和一个POST端点)。我们发现,多部分请求在到达内部PUT端点之前就已损坏 多部分数据似乎已从请求中删除。这似乎只适用于PUT请求,因为POST可以完美地工作 如果我们使用cURL直接命中内部PUT端点,那么请求将得到正确处理。相应的cURL命令和请求主体如下所示: curl -v -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file
curl -v -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8081/file/put"
curl -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8082/file/put"
标题:
{user agent=[curl/7.35.0],host=[localhost:8082],accept=[/],content length=[203],expect=[100 continue],content type=[multipart/form data;boundary=---------------------------c1efb86a9054e387]}
实体:
--------------------------c1efb86a9054e387内容配置:表单数据;name=“file”;filename=“helloworld.txt”内容类型:text/plain
这是我的文件内容
--------------------------c1efb86a9054e387--
但是,如果我们尝试通过Zuul使用cURL访问PUT端点,则请求如下所示:
curl -v -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8081/file/put"
curl -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8082/file/put"
标题:
{user agent=[curl/7.35.0],accept=[/],expect=[100 continue],content type=[multipart/form data;boundary=hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd],x-forwarded-host=[localhost:8081],x-forwarded-proto=[http],x-forwarded-prefix=[/file],x-forwarded-port=[8081],x-forwarded-for=[127.0.0.1],accept-encoding=[gzip],content-length=[38],host]=[localhost:8082],连接=[Keep Alive]}
实体:
--hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd--
请注意,实体是不完整的
我已将示例代码上载到此存储库:。存储库包含两个用于演示此问题的小项目。自述文件包含生成和运行说明
我知道请求最初由Spring的DispatcherServlet处理,然后最终由ZuulServlet处理。我相信是DispatcherServlet造成了问题。我们可以通过在所有请求URI前面加“/zuul”来绕过DispatcherServlet--这允许多部分请求直接转到ZuulServlet,然后按预期工作。但是这不是一个理想的修复方法
任何建议都将不胜感激。谢谢。好的,我有解决方案()
Spring Boot使用StandardServletMultipartResolver
来处理多部分-它假设所有多部分请求都将通过POST提交
为了允许StandardServletMultipartResolver处理PUT请求,我们必须重写isMultiPart
方法。我最终使用了以下配置:
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver() {
@Override
public boolean isMultipart(HttpServletRequest request) {
String method = request.getMethod().toLowerCase();
if (!Arrays.asList("put", "post").contains(method)) {
return false;
}
String contentType = request.getContentType();
return (contentType != null &&contentType.toLowerCase().startsWith("multipart/"));
}
};
}
此标准ServletMultipartResolver行为在即将发布的Spring版本(主分支)中发生更改。它们停止筛选方法并检查任何请求的“multipart”条件。