soufrk
soufrk

Reputation: 835

How to read HTTP 500 using a Spring RestTemplate client

A simple Spring Boot REST Controller

@PostMapping(path = "check-and-submit", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<MyOutput> checkAndSave(@RequestBody @Valid MyInput input, Errors errors){
    ResponseEntity<MyOutput> result = null;
    if (errors.hasErrors()) {
        result = new ResponseEntity<>(MyOutput.buildErrorResponse(errors), HttpStatus.INTERNAL_SERVER_ERROR);
    } else {
        myDao.save(input.buildEntity());
        result = new ResponseEntity<>(MyOutput.buildSuccessResponse(), HttpStatus.OK);      
    }
    return result;
}

And the test class for it

public static void main(String[] args) {    
    MyInput dto = new MyInput();
    // set properties
    RestTemplate restTemplate = new RestTemplate();
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
    headers.add("Content-Type", "application/json");
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    HttpEntity<MyInput> request = new HttpEntity<MyInput>(dto, headers);
    try {
        ResponseEntity<MyOutput> result = restTemplate.postForEntity(URL, request, MyOutput.class);
        System.out.println(result);
    } catch(Exception e) {
        e.printStackTrace();
    }
}

For success scenario this works fine. But, for exception scenrio, i.e. HTTP 500 this fails

org.springframework.web.client.HttpServerErrorException: 500 null
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:97)

As suggested in one of the posts, I created a error-handler that can successfully read the response

public class TestHandler extends DefaultResponseErrorHandler {

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        Scanner scanner = new Scanner(response.getBody());
        String data = "";
        while (scanner.hasNext())
            data += scanner.next();
        System.out.println(data);
        scanner.close();
    }
}

But how can I let RestTemplate read and deserialize the response JSON even in case of HTTP 500.

Before any other human-question-flagging-bot marks this as duplicate, here's a humble explanation on how this is different from the others.

All other questions address how to handle HTTP 500, at max read the response-body. This questions is directed at if it is possible to deserialize the response as JSON as well. Such functionality is well established in frameworks such as JBoss RESTEasy. Checking how same can be achieved in Spring.

Upvotes: 3

Views: 5435

Answers (1)

pvpkiran
pvpkiran

Reputation: 27068

This should work.

try {
      ResponseEntity<MyOutput> result = restTemplate.postForEntity(URL, request, MyOutput.class);
     } catch(HttpServerErrorException errorException) {
           String responseBody = errorException.getResponseBodyAsString();
           // You can use this string to create MyOutput pojo using ObjectMapper.
     }

Upvotes: 2

Related Questions