I've solved this issue with restTemplate.
Please, see some code examples:
public String uploadPhoto(File file, String token) throws ClientRequestException {
try {
MultiValueMap<String, Object> form = new LinkedMultiValueMap<String, Object>();
UrlResource urlr = new UrlResource("file:" + file.getAbsolutePath());
form.add("attachment", urlr);
WsUrl wsUrl = requestForObjectMultipart("/uploadProfilePhoto.json", form, WsUrl.class, token);
return wsUrl.getUrl();
} catch (MalformedURLException e) {
throw new ClientRequestException("Something went wrong with file upload");
}
}
protected <T extends ErrorAware> T requestForObjectMultipart(String methodUrl, Object r, Class<T> c, String token) throws ClientRequestException{
HttpHeaders headers = new HttpHeaders();
headers.add(SECURITY_TOKEN,token);
//Need to set content type here to avoid convertion with Jackson message converter
headers.add("Content-Type", "multipart/form-data");
return requestForObjectWithHeaders(methodUrl, r, c, HttpMethod.POST, headers);
}
protected <T extends ErrorAware> T requestForObjectWithHeaders(String methodUrl, Object r, Class<T> c, HttpMethod method, HttpHeaders headers) throws ClientRequestException{
T result = restTemplate.exchange( getBaseUrl() + getApiUrlPref() + methodUrl, method, new HttpEntity<Object>(r,headers), c).getBody();
if( result.hasError() )
throw new ClientRequestException(result.getError());
return result;
}
String token - it is only security token(provided ascustom HTTP header) on our rest services. It can serve an example how to setup "Custom headers" in request.
Note: pay attention that returned data(from web-service after upload file) is parsed as JSON object.
If you do not want this - you can simply ignore result of restTemplate.exchange() method.
My restTemplate initialization in Spring config:
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<ref bean="jsonConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter" />
</list>
</property>
...
</bean>
<!-- To enable @RequestMapping process on type level and method level -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter"/>
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
</bean>