Spring boot RestTemplate - multipart/mixed

三世轮回 提交于 2019-12-11 06:41:46

问题


Have a REST API which only accepts content type multipart/mixed.

Trying to use restTemplate and generate REST request with content type multipart/mixed. If I comment setContentType restTemplate defaults to multipart/form-data.

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

But no luck, any example how I can call API generating multipart/mixed request?

Maybe this helps

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:


So, unfortunately, there really is no way to solve your problem with the current implementation of Springs RestTemplate from "spring-web-4.3.12.RELEASE.jar". It assumes in all cases that the only type of multipart data is "multipart/form-data:, and so it does not recoignize the multipart nature of your request.

org.springframework.http.converter.FormHttpMessageConverter: lines 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;
}

If you look at the first part of the private method "isMultipart", you will see this:

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

It check to see if you have declared "multipart/form-data", but yours is "multipart/mixed", so it fails.

There are various other points at which it may also fail, but that's the root of the problem.

The only solution if you want to still use RestTemplate is to implement your own message converter that recognizes the desired media type, and add it to the templates message converters.

You could also write your own variation of RestTemplate by extending it, copy-paste and modify, or creating a client from scratch that uses something a bit more basic like apaches HttpClient (or even CORE java I suppose).



来源:https://stackoverflow.com/questions/46839788/spring-boot-resttemplate-multipart-mixed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!