Spring

ErrorHandling 을 통한 RestTemplate 공통 에러처리

기록만이살길 2020. 6. 14. 21:59
반응형

ErrorHandling 을 통한 RestTemplate 공통 에러처리

1. 개요

이 튜토리얼에서는 RestTemplate 인스턴스 에서 ResponseErrorHandler 인터페이스 를 구현, 관리하는 방법에대해 알아보겠습니다. 외부 API 호출 후 Best practice로 HTTP 응답을 처리하는 방법에 대해 알아보겠습니다.

2. 기본 오류 처리

기본적으로 RestTemplate 은 HTTP 오류의 경우 다음 예외 중 하나를 발생시킵니다.

  1. HttpClientErrorException

    – HTTP 상태 4xx 인 경우

  2. HttpServerErrorException –

    HTTP 상태 5xx 인 경우

  3. UnknownHttpStatusCodeException –

    알 수없는 HTTP 상태 인 경우

이 모든 예외는 RestClientResponseException의 확장입니다 .

분명히, 사용자 정의 오류 처리를 추가하는 가장 간단한 전략은 호출을 try / catch 블록 으로 래핑하는 것 입니다. 그런 다음 적발 된 예외를 처리합니다.

그러나이 간단한 전략은 원격 API 또는 호출 수가 증가함에 따라 확장 성이 떨어집니다. 모든 원격 호출에 재사용 가능한 오류 처리기를 구현할 수 있다면 더 효율적입니다.

3. ResponseErrorHandler 구현

따라서 ResponseErrorHandler 를 구현하는 클래스는 응답 에서 HTTP 상태를 읽고 다음 중 하나를 수행합니다.

  1. 우리 응용 프로그램에 의미있는 예외를 던져라
  2. HTTP 상태를 무시하고 응답 흐름을 중단없이 계속 진행하십시오.

ResponseErrorHandler 구현을 RestTemplate 인스턴스 에 주입해야 합니다.

따라서 RestTemplateBuilder 를 사용하여 템플릿 을 빌드 하고 응답 흐름에서 DefaultResponseErrorHandler 를 대체합니다 .

먼저 RestTemplateResponseErrorHandler를 구현해 봅시다 :

@Component
public class RestTemplateResponseErrorHandler 
  implements ResponseErrorHandler {

    @Override
    public boolean hasError(ClientHttpResponse httpResponse) 
      throws IOException {

        return (
          httpResponse.getStatusCode().series() == CLIENT_ERROR 
          || httpResponse.getStatusCode().series() == SERVER_ERROR);
    }

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

        if (httpResponse.getStatusCode()
          .series() == HttpStatus.Series.SERVER_ERROR) {
            // handle SERVER_ERROR
        } else if (httpResponse.getStatusCode()
          .series() == HttpStatus.Series.CLIENT_ERROR) {
            // handle CLIENT_ERROR
            if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
                throw new NotFoundException();
            }
        }
    }
}

다음으로, 우리는 건설 RestTemplate의 사용하여 인스턴스를 위해 RestTemplateBuilder을 우리의 소개 RestTemplateResponseErrorHandler를 :

@Service
public class BarConsumerService {

    private RestTemplate restTemplate;

    @Autowired
    public BarConsumerService(RestTemplateBuilder restTemplateBuilder) {
        RestTemplate restTemplate = restTemplateBuilder
          .errorHandler(new RestTemplateResponseErrorHandler())
          .build();
    }

    public Bar fetchBarById(String barId) {
        return restTemplate.getForObject("/bars/4242", Bar.class);
    }

}

4. 구현 테스트

마지막으로 서버를 조롱하고 NOT_FOUND 상태를 반환하여이 핸들러를 테스트 해 보겠습니다 .

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { NotFoundException.class, Bar.class })
@RestClientTest
public class RestTemplateResponseErrorHandlerIntegrationTest {

    @Autowired
    private MockRestServiceServer server;

    @Autowired
    private RestTemplateBuilder builder;

    @Test(expected = NotFoundException.class)
    public void  givenRemoteApiCall_when404Error_thenThrowNotFound() {
        Assert.assertNotNull(this.builder);
        Assert.assertNotNull(this.server);

        RestTemplate restTemplate = this.builder
          .errorHandler(new RestTemplateResponseErrorHandler())
          .build();

        this.server
          .expect(ExpectedCount.once(), requestTo("/bars/4242"))
          .andExpect(method(HttpMethod.GET))
          .andRespond(withStatus(HttpStatus.NOT_FOUND));

        Bar response = restTemplate 
          .getForObject("/bars/4242", Bar.class);
        this.server.verify();
    }
}

5. 결론

이 기사 에서는 HTTP 오류를 의미있는 예외로 변환 하는 RestTemplate에 대한 사용자 정의 오류 처리기를 구현하고 테스트하는 솔루션을 제시했습니다 .

항상 그렇듯이이 기사에 제시된 코드는 Github에서 사용할 수 있습니다 .

참고

https://www.baeldung.com/spring-rest-template-error-handling

반응형