title: 415 Unsupported Media Type while sending json file over REST Template
body: <p>I am trying to send a json file over REST Template. When I send it via POST man as MULTIPART_FORM_DATA, it works fine. The name I am supposed to give is specific (lets say <strong>aaa</strong>). Attached screenshot <a href="https://i.stack.imgur.com/zrS2K.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zrS2K.png" alt="screenshot"></a> of POSTMAN. But when I try same in code as specified in another stackoverflow <a href="https://stackoverflow.com/questions/45471648/sending-file-over-spring-rest-service-via-resttemplate?answertab=active#tab-top">post</a>, I get 415 Unsupported Media Type error as </p>
  
  <pre><code>org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
      at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
      at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:616) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
      at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:572) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
      at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:532) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
      at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:332) ~[spring-web-4.1.9.RELEASE.jar:4.1.9.RELEASE]
      at 
  </code></pre>
  
  <p><strong>Please do not mark it as duplicate as the specified answer did not work for me. Not sharing code as my code is exactly same as <a href="https://stackoverflow.com/questions/45471648/sending-file-over-spring-rest-service-via-resttemplate?answertab=active#tab-top">this</a> except</strong></p>
  
  <pre><code>requestParamerterMap.add("attachment", resource);
  </code></pre>
  
  <p>where as my code is</p>
  
  <pre><code>requestParamerterMap.add("aaa", resource);
  </code></pre>
  
  <p><strong>After debugging it from the server side, looks like request is reaching out to server. I was able to see below error in the server side:</strong></p>
  
  <pre><code>[{error=Unsupported Media Type, exception=org.springframework.web.HttpMediaTypeNotSupportedException, message=Content type 'application/octet-stream' not supported, status=415, timestamp=1532557180124}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@74d4827a]
  </code></pre>
  
  <p>So, from the server side logs, I am not sure where the content type is getting added as application/octet-stream as I have set the content type as </p>
  
  <pre><code>headers.setContentType(MediaType.MULTIPART_FORM_DATA);
  </code></pre>
  
  <p>Below is the code from server controller. Server side code uses Spring boot.</p>
  
  <pre><code>    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE,consumes = {"multipart/form-data"})
          @ResponseBody
          public MyResponse uploadPhoto(@RequestPart(value = "aaa", required = false) Optional&lt;MyRequest&gt; myRequest,
                                      @RequestPart(value = "file", required = false) Optional&lt;MultipartFile&gt; file,
                                      HttpServletRequest request) {
  //some logic
              return myResponse;
          }
  </code></pre>
  
  <p>The server code has an interceptor where I can see my request has content type as multipart/form-data. It does not reach to RestController</p>
  
  <p>When I debugged the server side code in 2 cases:</p>
  
  <ol>
  <li>POSTMAN request</li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/qnk1O.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/qnk1O.png" alt="enter image description here"></a></p>
  
  <ol start="2">
  <li>client code request</li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/kDxhj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/kDxhj.png" alt="enter image description here"></a></p>
  
  <p>One thing I figured out that file iteam has content type as <strong>application/json</strong> when I post from <strong>POSTMAN</strong> and the content type was <strong>application/octet-stream</strong> when the request goes from <strong>client side code</strong>.</p>
  
  <p>In my client side code, I am creating JSONObject as </p>
  
  <pre><code>JSONObject json = new JSONObject();
  json.append("myKey", "myValue");
  </code></pre>
  
  <p>and convert it to byte array as </p>
  
  <pre><code>json.toString().getBytes("UTF-8")
  </code></pre>
  
  <p>then I have followed <a href="https://stackoverflow.com/questions/45471648/sending-file-over-spring-rest-service-via-resttemplate?answertab=active#tab-top">this</a> . The difference in my code is, I am sending my JSONObject as byte stream as I can not create file (performance issues). </p>
  
  <p>And I cant not send JSONObject as string as server is expecting multipart-form-data for <strong>both file and aaa</strong></p>
  
  <p>I have created the restTemplate as </p>
  
  <pre><code> public RestTemplate myRestTemplate() {
  SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
          requestFactory.setReadTimeout(HTTP_CLIENT_TIMEOUT);
          requestFactory.setConnectTimeout(HTTP_CLIENT_TIMEOUT);
  
          RestTemplate restTemplate = new RestTemplate(requestFactory);
          List&lt;HttpMessageConverter&lt;?&gt;&gt; messageConverters = new ArrayList&lt;HttpMessageConverter&lt;?&gt;&gt;();
          messageConverters.add(new FormHttpMessageConverter());
          messageConverters.add(new StringHttpMessageConverter());
          restTemplate.setMessageConverters(messageConverters);
          return restTemplate;
  </code></pre>
  
  <p>Here is the client side code which calls the service:</p>
  
  <pre><code>public Optional&lt;JSONObject&gt; callService(byte[] multipartFile) {
          MultiValueMap&lt;String, Object&gt; body = new LinkedMultiValueMap&lt;&gt;();
          InputStream stream = new ByteArrayInputStream(multipartFile);
          MultipartByteArrayResource resource = new MultipartByteArrayResource(multipartFile,fileName);
  
  
         body.add("aaa", resource);
  
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.MULTIPART_FORM_DATA);
  
          HttpEntity&lt;MultiValueMap&lt;String, Object&gt;&gt; requestEntity = new HttpEntity&lt;&gt;(body, headers);
  
          try {
              response =  restTemplate.postForObject(url, requestEntity , String.class);
  
  
          } catch (Exception exception) {
              LOG.error("Error", exception);
              return Optional.empty();
          }
      }
  
     public class MultipartInputStreamFileResource extends InputStreamResource {
  
          private final String filename;
  
          MultipartInputStreamFileResource(InputStream inputStream, String filename) {
              super(inputStream);
              this.filename = filename;
          }
  
          @Override
          public String getFilename() {
              return this.filename;
          }
  
          @Override
          public long contentLength() throws IOException {
              return -1; // we do not want to generally read the whole stream into memory ...
          }
  }
  </code></pre>
  
  <p>And same code works when I send file (note <strong>file</strong> and <strong>aaa</strong> are two different things though both are <strong>multipart/form-data</strong> in server side. <strong>file</strong> is just a <strong>file of any time (image/text/pdf)</strong> but <strong>aaa</strong> is <strong>json data file</strong>)</p>
  
  <p>After debugging little bit more, what I observed is server side controller is expecting the file content to be json as Jackson try to deserialize that json to <strong>MyRequest</strong> object. When I send post from POSTMAN, it has the json content so working as expected but from the client side code, the content is <strong>byteArray</strong>, and its not getting deserialize to <strong>MyRequest</strong> object. Not sure how to fix this </p>