0

In my Service there was Jersey client implementation to call a rest API now I was migrating this code to RestTemplate. In old code when there was a 401 error that comes as a response from the backend and I store the response in an object.

But when I migrated the code to RestTeplate the 401 is caught by HttpClientErrorException class so I am not able to get the response since the code flow goes to the catch block.

Jersey Client code

public Employees getEmployees1() throws MyException {
        Employee employee=new Employee(23, "Test", "Test", "Test@test.com");
        
        ClientResponse response=null;
        try {
            Client client = Client.create();
            WebResource webResource = client.resource("http://localhost:8080/employees/");
            response = webResource.accept("application/json")
                    .type("application/json").header("Authorization", "invalid Data").post(ClientResponse.class, employee);

        }catch (RuntimeException e) {
            logger.error("Runtime Error Occured -{} Response - {} ",e.getMessage(),response.getStatus());
            throw new MyException("Unexpected Error Occured",e);
        }catch (Exception e) {
            logger.error("Some Error Occured -{} Response - {} ",e.getMessage(),response.getStatus());
            throw new MyException("Unexpected Error Occured",e);
        }
        return response.readEntity(Employees.class);
    }

RestTemplate Code

public Employees getEmployees() throws MyException {
    Employee employee=new Employee(23, "Test", "Test", "Test@test.com");
    HttpHeaders headers=new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    headers.add(HttpHeaders.AUTHORIZATION, "invalid Data");
    ResponseEntity<Employees> response=null;
    try {
        response = this.restTemplate.exchange("http://localhost:8080/employees/", HttpMethod.POST, new HttpEntity<Employee>(employee,headers), Employees.class);
    }catch (RuntimeException e) {
        logger.error("Runtime Error Occured -{} Response - {} ",e.getMessage(),response.getStatusCode());
        throw new MyException("Unexpected Error Occured",e);
    }catch (Exception e) {
        logger.error("Some Error Occured -{} Response - {} ",e.getMessage(),response.getStatusCode());
        throw new MyException("Unexpected Error Occured",e);
    }
    return response.getBody();
}

2 Answers2

0

By default RestTemplate throws an HttpStatusCodeException (a child of it) for all 400+ status codes - see DefaultResponseErrorHandler. You can change this behavior by setting your own implementation of ResponseErrorHandler to RestTemplate using setErrorHandler or if RestTemplate is constructed using RestTemplateBuilder - using errorHandler method of the builder.

silh
  • 264
  • 2
  • 7
  • Hi, @silh Thanks for your response, but in the rest-client code when 401 is returned it also contains a body but when I used the rest template it only gives 401 with no body, how to approach this? – Nalin Kumar Jul 04 '22 at 11:01
  • @NalinKumar I might be easier to catch HttpStatusCodeException, check it's type, call `getResponseBodyAsString` on it and then parse it with ObjectMapper into the type you need. – silh Jul 04 '22 at 14:59
  • Thanks, @silh, I solved this issue by implementing ResponseErrorHandler. – Nalin Kumar Jul 04 '22 at 15:26
0

I used the default ResponseErrorHandler, by using this it will bypass all the ResponseError exception

RestTemplate rt =  restTemplateBuilder.errorHandler(new ResponseErrorHandler(){
            @Override
            public boolean hasError(ClientHttpResponse response) throws IOException {
                return false;
            }
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
            }})
        .build();