1. 개요
이 짧은 예제에서는 RestTemplate 인스턴스 에 ResponseErrorHandler 인터페이스 를 구현하고 삽입하는 방법을 설명합니다 . 원격 API에서 반환 된 HTTP 오류를 정상적으로 처리합니다.
2. 기본 오류 처리
기본적으로 RestTemplate 은 HTTP 오류가 발생한 경우 다음 예외 중 하나를 발생시킵니다.
- HttpClientErrorException – HTTP 상태 4xx의 경우
- HttpServerErrorException – HTTP 상태 5xx의 경우
- UnknownHttpStatusCodeException – 알 수없는 HTTP 상태의 경우
이러한 모든 예외는 RestClientResponseException의 확장입니다 .
분명히 사용자 지정 오류 처리를 추가하는 가장 간단한 전략은 try / catch 블록 에서 호출을 래핑하는 것 입니다. 그런 다음 적절하다고 판단되는대로 포착 된 예외를 처리합니다.
그러나이 간단한 전략은 원격 API 또는 호출 수가 증가함에 따라 확장되지 않습니다 . 모든 원격 호출에 대해 재사용 가능한 오류 처리기를 구현할 수 있다면 더 효율적일 것입니다.
3. ResponseErrorHandler 구현
따라서 ResponseErrorHandler 를 구현하는 클래스는 응답 에서 HTTP 상태를 읽고 다음 중 하나를 수행합니다.
- 애플리케이션에 의미있는 예외를 던집니다.
- HTTP 상태를 무시하고 중단없이 응답 흐름을 계속하십시오.
RestTemplate 인스턴스에 ResponseErrorHandler 구현 을 삽입해야 합니다.
따라서 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에 대한 사용자 지정 오류 처리기를 구현하고 테스트하는 솔루션을 제시했습니다 .
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/spring-rest-template-error-handling
'Java' 카테고리의 다른 글
Spring Boot에서 Keycloak 사용에 대한 빠른 사용방법(예제) (0) | 2021.03.28 |
---|---|
Spring Boot에서 프로필에 대한 Security 비활성화 (0) | 2021.03.27 |
Spring RestTemplate 인터셉터 사용 (0) | 2021.03.27 |
Double.parseDouble에서 Parse를 호출하기 전에 null 확인 (0) | 2021.03.27 |
Java 메서드에서 여러 값을 반환하는 방법 (0) | 2021.03.27 |