使用 RestTemplate 时,如何在分段上传中为文件设置内容类型(从 rest 客户端)

我尝试上传的文件将始终是一个xml文件。我想将内容类型设置为 application/xml 这是我的代码:

         MultiValueMap<String, Object parts = new LinkedMultiValueMap<String,
         Object(); parts.add("subject", "some info"); 
         ByteArrayResource xmlFile = new    ByteArrayResource(stringWithXMLcontent.getBytes("UTF-8")){
                 @Override
                 public String getFilename(){
                     return documentName;
                 }             
             };

     parts.add("attachment", xmlFile);

//sending the request using RestTemplate template;, the request is successfull 
String result = template.postForObject(getRestURI(), httpEntity,String.class);      
//but the content-type of file is 'application/octet-stream'

原始请求如下所示:

    Content-Type:
    multipart/form-data;boundary=gbTw7ZJbcdbHIeCRqdX81DVTFfA-oteHHEqgmlz
    User-Agent: Java/1.7.0_67 Host: some.host Connection: keep-alive
    Content-Length: 202866

    --gbTw7ZJbcdbHIeCRqdX81DVTFfA-oteHHEqgmlz Content-Disposition: form-data;    name="subject" Content-Type: text/plain;charset=ISO-8859-1
    Content-Length: 19

    some info

    --gbTw7ZJbcdbHIeCRqdX81DVTFfA-oteHHEqgmlz Content-Disposition: form-data;   name="attachment"; filename="filename.xml" Content-Type:
    application/octet-stream Content-Length: 201402

    ....xml file contents here ..

文件的内容类型被生成为“应用程序/八位字节流”,我希望它是“应用程序/ xml” 如何设置文件的内容类型?


答案 1

我从这个链接中获取提示后找到了解决方案:

使用压缩的jpeg字节数组和spring为android制作多部分发布请求

解决方案是将 ByteArrayResource 放在具有所需标头的 HttpEntity 中,并将 HttpEntity 添加到多值映射(而不是添加 ByteArrayResource 本身)。

法典:

Resource xmlFile = new ByteArrayResource(stringWithXMLcontent.getBytes("UTF-8")){
            @Override
            public String getFilename(){
                return documentName;
            }
        };
        HttpHeaders xmlHeaders = new HttpHeaders();
        xmlHeaders.setContentType(MediaType.APPLICATION_XML);
        HttpEntity<Resource> xmlEntity = new HttpEntity<Resource>(xmlFile, xmlHeaders);
        parts.add("attachment", xmlEntity);

答案 2

由于我无法评论@RGR的答案,我将其作为新答案发布,尽管RGR的答案是绝对正确的。

问题是,Sprint RestTemplates使用FormHttpMessageConverter发送多部分请求。此转换器检测从 Resource 继承的所有内容,并将其用作请求的“文件”部分,例如,如果您使用 MultiValueMap,则只要您添加“资源”,就会立即将其自己的部分发送到它自己的部分...-->设置文件名,Mime 类型,长度,..不会是“文件部分”的一部分。

这不是一个答案,但它解释了为什么必须扩展ByteArrayResource以返回文件名并作为请求的唯一部分发送。发送多个文件将与多值地图一起使用

看起来此行为已在 Spring 4.3 中通过 SPR-13571 修复