spring-Zuul / DispatcherServlet破坏了包含多部分的PUT请求(多部分数据已删除)
作者:互联网
我们正在使用Zuul将请求转发到内部微服务.内部服务有2个端点(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"
Headers:
{user-agent=[curl/7.35.0], host=[localhost:8082], accept=[/], content-length=[203], expect=[100-continue], content-type=[multipart/form-data; boundary=————————c1efb86a9054e387]}
Entity:
————————–c1efb86a9054e387 Content-Disposition: form-data; name=”file”; filename=”helloworld.txt” Content-Type: text/plain
this is my file content
————————–c1efb86a9054e387–
但是,如果我们尝试通过Zuul使用cURL命中PUT端点,则请求如下所示:
curl -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8082/file/put"
Header:
{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], connection=[Keep-Alive]}
Entity:
–hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd–
请注意,实体不完整.
我已将示例代码上传到此存储库:https://github.com/trcodestore/zuul-put-demo.该存储库包含2个用于演示此问题的小项目.自述文件包含构建和运行说明.
我知道请求最初由Spring的DispatcherServlet处理,然后最终由ZuulServlet处理.我相信是造成此问题的DispatcherServlet.我们可以通过为所有请求URI加上前缀“ / zuul”来绕开DispatcherServlet -这允许将多部分请求直接发送到ZuulServlet,然后按预期运行.但是,这不是理想的解决方案.
任何意见,将不胜感激.谢谢.
解决方法:
好的,我有解决方案(credit: Mohammad Zolmajd).
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/"));
}
};
}
标签:spring-cloud-netflix,spring-boot,netflix-zuul,multipart,spring 来源: https://codeday.me/bug/20191026/1934534.html