Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why RestTemplate GET response is in JSON when should be in XML?

I struggled with an extrange spring behavior using RestTemplate (org.springframework.web.client.RestTemplate) without success.

I use in my hole application below code and always receive an XML response, which I parse and evaluate its result.

String apiResponse = getRestTemplate().postForObject(url, body, String.class);

But can't figure out why a server response is in JSON format after executing:

String apiResponse = getRestTemplate().getForObject(url, String.class);

I've debugged at low level RestTemplate and the content type is XML, but have no idea why the result is in JSON.

When I access from a browser the response is also in XML, but in apiResponse I got JSON.

I tried many options after reading Spring documentation http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/web/client/RestTemplate.html

Also tried to modify explicitly the headers but still can't figure it out.

I debugged RestTemplate class and noticed that this method is always setting application/json:

public void doWithRequest(ClientHttpRequest request) throws IOException {
            if (responseType != null) {
                List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
                for (HttpMessageConverter<?> messageConverter : getMessageConverters()) {
                    if (messageConverter.canRead(responseType, null)) {
                        List<MediaType> supportedMediaTypes = messageConverter.getSupportedMediaTypes();
                        for (MediaType supportedMediaType : supportedMediaTypes) {
                            if (supportedMediaType.getCharSet() != null) {
                                supportedMediaType =
                                        new MediaType(supportedMediaType.getType(), supportedMediaType.getSubtype());
                            }
                            allSupportedMediaTypes.add(supportedMediaType);
                        }
                    }
                }
                if (!allSupportedMediaTypes.isEmpty()) {
                    MediaType.sortBySpecificity(allSupportedMediaTypes);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Setting request Accept header to " + allSupportedMediaTypes);
                    }
                    request.getHeaders().setAccept(allSupportedMediaTypes);
                }
            }
        }

Could you give an idea?

like image 532
Federico Piazza Avatar asked Feb 06 '14 20:02

Federico Piazza


1 Answers

I could solve my issue with RC.'s help. I'll post the answer to help other people.

The problem was that Accept header is automatically set to APPLICATION/JSON so I had to change the way to invoke the service in order to provide the Accept header I want.

I changed this:

String response = getRestTemplate().getForObject(url, String.class);

To this in order to make the application work:

// Set XML content type explicitly to force response in XML (If not spring gets response in JSON)
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);

ResponseEntity<String> response = getRestTemplate().exchange(url, HttpMethod.GET, entity, String.class);
String responseBody = response.getBody();
like image 115
Federico Piazza Avatar answered Sep 20 '22 14:09

Federico Piazza