Spring Boot RestTemplate - multipart / mixed

时间:2017-10-19 22:26:04

标签: spring-boot multipart resttemplate

拥有一个只接受内容类型multipart / mixed的REST API。

尝试使用restTemplate并生成内容类型为multipart / mixed的REST请求。 如果我评论setContentType,则restTemplate默认为multipart / form-data。

setContentType(MediaType.parseMediaType("multipart/mixed"))

但是没有运气,我是如何调用API生成多部分/混合请求的?

也许这有帮助

HttpHeaders publishHeaders = new HttpHeaders();
publishHeaders.set(HEADER_TABLEAU_AUTH, token);
publishHeaders.setContentType(MediaType.parseMediaType("multipart/mixed"));
String response;
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
String payload = "<tsRequest>\n" +
        ............................
       "</tsRequest>";
map.add(TABLEAU_PAYLOAD_NAME, payload);
map.add("tableau_datasource", new FileSystemResource("/extract/test.tde"));
HttpEntity<LinkedMultiValueMap<String, Object>> entity = new HttpEntity<>(map, publishHeaders);
try {
response = restTemplate.postForObject(url + PUBLISH_DATASOURCE_SINGLE_CHUNK, entity, String.class, siteId);
} catch (RestClientException restEx) {
   log.error(....);
   throw restEx;
}

1 个答案:

答案 0 :(得分:1)

所以,遗憾的是,从Spring-web-4.3.12.RELEASE.jar中解决当前Spring RestTemplate的实现问题确实无法解决问题。它假定在​​所有情况下,唯一类型的多部分数据是“multipart / form-data:”,因此它不会重新标记您请求的多部分性质。

org.springframework.http.converter.FormHttpMessageConverter:第247-272行

@Override
@SuppressWarnings("unchecked")
public void write(MultiValueMap<String, ?> map, MediaType contentType, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException {

    if (!isMultipart(map, contentType)) {
        writeForm((MultiValueMap<String, String>) map, contentType, outputMessage);
    }
    else {
        writeMultipart((MultiValueMap<String, Object>) map, outputMessage);
    }
}


private boolean isMultipart(MultiValueMap<String, ?> map, MediaType contentType) {
    if (contentType != null) {
        return MediaType.MULTIPART_FORM_DATA.includes(contentType);
    }
    for (String name : map.keySet()) {
        for (Object value : map.get(name)) {
            if (value != null && !(value instanceof String)) {
                return true;
            }
        }
    }
    return false;
}

如果你看一下私有方法“isMultipart”的第一部分,你会看到:

    if (contentType != null) {
        return MediaType.MULTIPART_FORM_DATA.includes(contentType);
    }

检查你是否声明了“multipart / form-data”,但你的是“multipart / mixed”,所以它失败了。

还有其他各种方面也可能失败,但这是问题的根源。

如果您仍想使用RestTemplate,唯一的解决方案是实现您自己的消息转换器,该转换器可识别所需的媒体类型,并将其添加到模板消息转换器。

您还可以编写自己的RestTemplate变体,方法是扩展它,复制粘贴和修改,或者从头开始创建一个客户端,使用更基本的东西,比如apach HttpClient(甚至是我认为的CORE java)。