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?
Set the content-type header value to MediaType. MULTIPART_FORM_DATA. When this header is set, RestTemplate automatically marshals the file data along with some metadata. Metadata includes file name, file size, and file content type (for example text/plain):
Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.
Uploading files in a form using multipart/form-data The standard way to upload files in a web application is to use a form with a special multipart/form-data encoding, which lets you mix standard form data with file attachment data. Note: The HTTP method used to submit the form must be POST (not GET ).
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);
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. e.g. 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With