Invalid mime type in spring rest template?

17,651

Short answer in my case was add these extra headers while before making the request.

headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
headers.add(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.name());

Long answer: Thanks to Nikolay Shevchenko's suggestion to use debugger to dig out that when there was an error on the server RestTemplate tried to gather up all headers and body from the response to create sane exception message. While trying to create that message from response it got the mime type

text/plain, application/json, application/json, application/*+json, application/*+json, */*; charset=UTF-8

Yes that entire length of text instead of application/json; charset=UTF-8 as shown for the same request by Postman. So in my case of an older spring rest template version when it tries to parse over the above provided mime type, it fails, producing this message.

org.springframework.http.InvalidMediaTypeException: Invalid mime type "text/plain, application/json, application/json, application/*+json, application/*+json, */*; charset=UTF-8": Invalid token character ',' in token "plain, application/json, application/json, application/*+json, application/*+json, */*"

So instead of a getting a server error, a more fine grained mime type exception bubbles up from deeper stack, making no sense for what you are searching for.

As per this post by M. Deinum RestTemplate was some how ending up using StringHttpMessageConverter although I have specified Jackson to Http Message converter as shown below.

restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

As mentioned in aforementioned post having StringHttpMessageConverter causes writeAcceptCharset to be true which brings along the long format of mime type with almost every possible value. In the mentioned post the solutions were either to make writeAcceptCharset as false or not to write plain string but use object and then marshal it as a string.

For my use case I was expecting response type to be application/json with charset of UTF-8 so setting up those accept headers in configuration sorted out my problem.

Share:
17,651
Soham
Author by

Soham

Java developer.

Updated on June 04, 2022

Comments

  • Soham
    Soham almost 2 years

    I am just trying to make a simple REST request like below

    String url = "some url";
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
    headers.add(HttpHeaders.AUTHORIZATION, "some authorization");
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    Body body = new Body();
    body.setRemarks("test");
    org.springframework.http.HttpEntity request = new org.springframework.http.HttpEntity(body, headers);
    try {
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, request, String.class);
        System.out.println("Status Response: "+ response.getStatusCode() +". Body: "+ response.getBody());
    } catch (HttpClientErrorException | HttpServerErrorException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    Problem is every time I do this in Java the result is unpredictable I am usually getting this error consistently.

    org.springframework.http.InvalidMediaTypeException: Invalid mime type "text/plain, application/json, application/json, application/*+json, application/*+json, */*; charset=UTF-8": Invalid token character ',' in token "plain, application/json, application/json, application/*+json, application/*+json, */*"
    at org.springframework.http.MediaType.parseMediaType(MediaType.java:452)
    at org.springframework.http.HttpHeaders.getContentType(HttpHeaders.java:745)
    at org.springframework.web.client.DefaultResponseErrorHandler.getCharset(DefaultResponseErrorHandler.java:115)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
    

    However when I try the same request through postman it works. I am missing something very simple and I do not know what.

    I checked the response from Postman and the headers, and they seem to hold good like Content-Type →application/json; charset=UTF-8 and the response is also well formed.

    I am also not able to make out which part whether the request or the response is on which Rest Template is having a problem.

    • Nikolai  Shevchenko
      Nikolai Shevchenko about 6 years
      Try to place jackson converter on first position restTemplate.getMessageConverters().add(0, new MappingJackson2HttpMessageConverter());. If it doesn't help then I suggest you to use debugger and descent deeply into RestTemplate.
    • Subin Chalil
      Subin Chalil about 6 years
      give us a fulle restController code.
    • Soham
      Soham about 6 years
      @SubinCPoonamgode I do not have the controller code, this is on the REST client API I am trying to hit, and build by their team. I am able to hit it with Postman successfully.