ErrorHandling 을 통한 RestTemplate 공통 에러처리
1. 개요
이 튜토리얼에서는 RestTemplate 인스턴스 에서 ResponseErrorHandler 인터페이스 를 구현, 관리하는 방법에대해 알아보겠습니다. 외부 API 호출 후 Best practice로 HTTP 응답을 처리하는 방법에 대해 알아보겠습니다.
2. 기본 오류 처리
기본적으로 RestTemplate 은 HTTP 오류의 경우 다음 예외 중 하나를 발생시킵니다.
HttpClientErrorException
– HTTP 상태 4xx 인 경우
HttpServerErrorException –
HTTP 상태 5xx 인 경우
UnknownHttpStatusCodeException –
알 수없는 HTTP 상태 인 경우
이 모든 예외는 RestClientResponseException의 확장입니다 .
분명히, 사용자 정의 오류 처리를 추가하는 가장 간단한 전략은 호출을 try / catch 블록 으로 래핑하는 것 입니다. 그런 다음 적발 된 예외를 처리합니다.
그러나이 간단한 전략은 원격 API 또는 호출 수가 증가함에 따라 확장 성이 떨어집니다. 모든 원격 호출에 재사용 가능한 오류 처리기를 구현할 수 있다면 더 효율적입니다.
3. ResponseErrorHandler 구현
따라서 ResponseErrorHandler 를 구현하는 클래스는 응답 에서 HTTP 상태를 읽고 다음 중 하나를 수행합니다.
- 우리 응용 프로그램에 의미있는 예외를 던져라
- 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
'Spring' 카테고리의 다른 글
RestTemplate을 통해 파일 업로드하기 (0) | 2020.06.15 |
---|---|
RestTemplate Interceptor활용하기 (0) | 2020.06.15 |
RestTemplateBuilder로 안전하게 restTemplate 생성하기 (1) | 2020.06.14 |
RestTemplate에서 List 다루기 (0) | 2020.06.14 |
RestTemaplte 사용방법 (0) | 2020.06.13 |