Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set content-type for the file in multipart upload when using RestTemplate (from a rest client)

Tags:

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?

like image 491
RGR Avatar asked Feb 06 '15 19:02

RGR


People also ask

How do I pass a multipart file in RestTemplate?

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):

How do I upload a file to multipart?

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.

What is the use of multipart file upload in Java?

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 ).


Video Answer


2 Answers

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); 
like image 140
RGR Avatar answered Sep 18 '22 13:09

RGR


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

like image 27
Nesta Avatar answered Sep 20 '22 13:09

Nesta