Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring REST - Can a RestTemplate consume multipart/mixed?

I want to write a REST service which does responed with a zipFile and some json data, everything in one multipart/mixed request.

The server part works fine and i am testing it with the REST Client from firefox. My Server sends a multipart like this

--k-dXaXvCFusLVXUsg-ryiHMmkdttadgcBqi4XH

Content-Disposition: form-data; name="form"
Content-type: application/json

{"projectName":"test","signal":"true"}

--k-dXaXvCFusLVXUsg-ryiHMmkdttadgcBqi4XH
Content-Disposition: form-data; name="file2"; filename="file2.txt"
Content-type: application/octet-stream
Content-Length: 10

hallo=Welt

I know that RestTemplate can send multiparts with the help of a MultiValueMap out of the box.

Now I tried to consume multipart/mixed responses and return a MultiValueMap

@Component
public class RestCommand 
extends AbstractLoginRestCommand<Form, MultiValueMap<String, Object>>
{
    @Override
    protected MultiValueMap<String, Object> executeInternal ( Form form )
    {
        RestTemplate restTemplate = getRestTemplate();
        MyMultiValueMap map = restTemplate.postForObject(getUrl(), form, MyMultiValueMap.class);
        return new LinkedMultiValueMap<String, Object>(map);
    }
}

class MyMultiValueMap extends LinkedMultiValueMap<String, Object>
{}

MyMultiValueMap exist to prevent type erasure (generics).

This gives

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class org.jlot.client.remote.MyMultiValueMap] and content type [multipart/form-data;boundary=Rjh-fkdsI9OIyPpYwdFY7lsUIewhRSX8kE19I;charset=UTF-8] at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:107) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:492)

Javadoc of FormHttpMessageConverter says it can write but not read multipart/form-data.

Why is it like this?

Is there a way to read multipart/form-data with RestTemplate out-of-the-box or do I need to write a HttpMessageConverter?

like image 613
Janning Avatar asked Dec 17 '12 16:12

Janning


People also ask

Why RestTemplate is deprecated?

RestTemplate provides a synchronous way of consuming Rest services, which means it will block the thread until it receives a response. RestTemplate is deprecated since Spring 5 which means it's not really that future proof.

Does RestTemplate support all HTTP methods?

Rest Template is used to create applications that consume RESTful Web Services. You can use the exchange() method to consume the web services for all HTTP methods.


1 Answers

I had the same issue and I think I achieved what you wanted. You just have to override the canRead method of the form converter. With your example something like below should work.

FormHttpMessageConverter formConverter = new FormHttpMessageConverter() {
    @Override
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        if (clazz == MyMultiValueMap.class) {
            return true;
        }
        return super.canRead(clazz, mediaType);
    }
};

And add this converter to your rest template.

like image 98
FabiF Avatar answered Oct 01 '22 22:10

FabiF