8

I have simple java spring method for creating object

RestTemplate restTemplate = new RestTemplate();
Address address = restTemplate.getForObject(url, Address.class);

But the server responds me JSON string with wrong Content-Type: text/plain instead of application/json (checked in Postman). And I get the exception:

Could not extract response: no suitable HttpMessageConverter found for response type [class Address] and content type [text/plain;charset=utf-8]

So I think, I need change response header Content-Type to right application/json, that MappingJackson2HttpMessageConverter find out JSON string and run code as well.

Dmitry Torshin
  • 113
  • 1
  • 6

3 Answers3

16

After trying for an hour, I found a short and easy way.

Json converter by default supports only "application/json". We just override it to support "text/plain".

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

// support "text/plain"
converter.setSupportedMediaTypes(Arrays.asList(TEXT_PLAIN, APPLICATION_JSON));

RestTemplate template = new RestTemplate();
template.getMessageConverters().add(converter);

// It's ok now
MyResult result = tmp.postForObject("http://url:8080/api", 
            new MyRequest("param value"), MyResult.class);
Prashant_M
  • 2,868
  • 1
  • 31
  • 24
Neo Pham
  • 362
  • 3
  • 9
2

Thank you for help! In case I can't change response's header. I create new response object with right header.

            ClientHttpRequest clientHttpRequest = new SimpleClientHttpRequestFactory().createRequest(URI.create(str), org.springframework.http.HttpMethod.GET);
            final ClientHttpResponse clientHttpResponse = clientHttpRequest.execute();
            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            Address address = new Address();
            //It always true, because service always returns 200 OK
            if (clientHttpResponse.getStatusCode() == HttpStatus.OK) {
                address = (Address) converter.read(address.getClass(), new HttpInputMessage() {
                    public InputStream getBody() throws IOException {
                        return clientHttpResponse.getBody();
                    }

                    public HttpHeaders getHeaders() {
                        HttpHeaders httpHeaders = new HttpHeaders();
                        httpHeaders.putAll(clientHttpResponse.getHeaders());
                        httpHeaders.put("Content-Type", Collections.singletonList(MediaType.APPLICATION_JSON_VALUE));
                        return httpHeaders;
                    }
                });
                busStop.setNearestAddress(address.toString());
            }

I'm sure it isn't simple and good solution, but It works.

Dmitry Torshin
  • 113
  • 1
  • 6
0

To set the content type for your request you could do something like:

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity entity = new HttpEntity(headers);
    ResponseEntity<Address> response = restTemplate.exchange(url, HttpMethod.GET,  entity, Address.class);
    Address address = response.getBody();
  • 1
    No, it doesn't work. It just change headers of request, but not response. – Dmitry Torshin Mar 05 '17 at 14:10
  • You can't change the headers for Response, those headers are sent by the server, so, unless you're writing the server's code there is no way to do what you want. – Orlando Vargas Mar 06 '17 at 17:16
  • Check this similar question http://stackoverflow.com/questions/24723394/could-not-extract-response-no-suitable-httpmessageconverter-found-for-response – Orlando Vargas Mar 06 '17 at 17:21