Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 具有多部分的PUT请求被Zuul/DispatcherServlet损坏(多部分数据被删除)_Spring_Spring Boot_Multipart_Netflix Zuul_Spring Cloud Netflix - Fatal编程技术网

Spring 具有多部分的PUT请求被Zuul/DispatcherServlet损坏(多部分数据被删除)

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

我们正在使用Zuul将请求转发到内部微服务。内部服务有两个端点(一个PUT端点和一个POST端点)。我们发现,多部分请求在到达内部PUT端点之前就已损坏

多部分数据似乎已从请求中删除。这似乎只适用于PUT请求,因为POST可以完美地工作

如果我们使用cURL直接命中内部PUT端点,那么请求将得到正确处理。相应的cURL命令和请求主体如下所示:

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”条件。