Programming/Spring Boot

RestTemplate 4xx, 5xx Code 처리하는 방법 (HttpClientException)

Jan92 2021. 10. 4. 23:01

HttpClientException$BadRequest: 400

 

RestTemplate이란 간략하게 spring framework 3.0부터 지원되는 http 통신에 사용되는 템플릿입니다.

RESTful 형식을 따르며 json, xml 형식의 데이터를 쉽게 받을 수 있습니다.

 

* RestTemplate에 대한 자세한 내용은 다루지 않고 해당 에러에 관한 내용만 다루는 포스팅입니다.

 

 

 

{
    "state": 400,
    "data": [],
    "result": "fail",
    "message": "QR 코드의 유효기간이 지났습니다.",
    "error": []
}

 

RestTemplate의 문제점 중 하나는 위 예시의 json 데이터 처럼 4xx, 5xx의 응답 코드를 받았을 때 Exception을 발생시킨다는 것인데요.

통신을 하다보면 200 상태의 success 뿐만 아니라 4xx, 5xx의 결과 코드도 받아서 처리해야 하는 경우가 있습니다. 이때 처리할 수 있는 방법을 알아보겠습니다.

 

 


 

 

DefaultResponseErrorHandler

4xx, 5xx 결과 코드를 처리하기 위해 어디서 해당 코드를 처리하는지 알아보기 위해 RestTemplate.class에 접근해봤습니다.

RestTemplate은 기본적으로 ResponseErrorHandler interface의 구현체인 DefaultResponseErrorHandler class를 사용하여 에러 처리를 하고 있습니다.

 

 

 

handleError method

DefaultResponseErrorHandler 클래스의 handleError method입니다.

 

switch 부분을 보면 statusCode.series()의 값에 따라 HttpClientErrorException을 던지는 것을 볼 수 있습니다.

위 에러는 해당 코드를 통해 발생된 것이라는 걸 확인할 수 있습니다.

 

 

 

HttpStatus enum

 

 


 

 

import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

import java.io.IOException;

public class RestTemplateErrorHandler implements ResponseErrorHandler {
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return false;
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {

    }
}

 

그렇다면 4xx, 5xx 코드가 발생했을 때의 처리 방법은 RestTemplate이 Default로 설정된 DefaultResponseErrorHandler 클래스가 아닌 직접 만든 Handler 클래스를 사용하게 하는 것인데요.

ResponseErrorHandler interface를 구현하는 CustomErrorHandler를 생성합니다.

 

 

restTemplate.setErrorHandler(new RestTemplateErrorHandler());
String result = restTemplate.postForObject(url, httpEntity, String.class);

 

그리고 RestTemplate의 setErrorHandler() 메서드를 통해 직접 생성한 CustomErrorHandler를 추가합니다.

 

이렇게 되면 4xx, 5xx 결과 코드로 넘어오는 데이터도 HttpClientErrorException이 아닌 개발자가 원하는 방식으로 처리할 수 있게 됩니다.