The file i'm trying to upload will always be a xml file. I want to set the content-type as application/xml Here is my code:
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'
the raw request looks like this:
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 ..
The content-type of the file is being generated as 'application/octet-stream' where as i want it to be 'application/xml' How can i set the content type for the file?
I figured out the solution after taking hint from this link:
Making a multipart post request with compressed jpeg byte array with spring for android
Solution is to put the ByteArrayResource in a HttpEntity with required header and add the HttpEntity to Multivaluemap (Instead of adding ByteArrayResource itself.)
Code:
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);
I've not used RestTemplate but i've used HttpClient in past - This is how i pass the body part -
MultipartEntityBuilder eb = MultipartEntityBuilder.create().setBoundary(MULTIPART_BOUNDARY)
.addTextBody(BODYPART_ENTITY, key, ContentType.create("application/xml", Charset.forName("UTF-8")));
You will have to look at for API in RestTemplate which can take content-type
As i can not comment the answer of @RGR I'm posting this as new answer although RGR's answer is absolutely correct.
The problem is, that the Sprint RestTemplates uses FormHttpMessageConverter to send the multi part request. This converter detects everything that inherits from Resource and uses this as the request's "file" part. eg If you use a MultiValueMap every property you add will be send in it's own part as soon as you add a "Resource"...--> Setting filename, Mime-Type, length,.. will not be part of the "file part".
Not an answer, but it's the explanation why ByteArrayResource must be extended to return the filename and be send as the only part of the request. Sending multiple files will work with a MultiValueMap
It looks like this behaviour was fixed in Spring 4.3 by SPR-13571
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.