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