Spring Framework에서 RESTful 웹 서비스와 통신하기 위한 동기식 클라이언트로 HTTP 요청을 쉽게 보내고 응답을 받을 수 있도록 도와주는 유틸리티 클래스다.
RestTemplate은 기본적으로 Connection Pooling을 지원하지 않기 때문에 RestTemplate이 기본적으로 사용하는 URLConnection 대신 apache에서 제공하는 HttpClient를 사용하면 connection pooling이 가능합니다.
HttpClient 의존성 추가
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
Configuration
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() throws Exception{
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(5000); // read timeout (ms)
factory.setConnectTimeout(3000); // connection timeout (ms)
//Apache HttpComponents HttpClient
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setMaxConnTotal(50) //최대 커넥션 수
.setMaxConnPerRoute(20) //각 호스트(IP와 Port의 조합)당 커넥션 풀에 생성가능한 커넥션 수
.build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);
return restTemplate;
}
}
exchange
exchange() 메서드는 Spring에서 RESTful API와 통신할 때 가장 유연한 방식 중 하나로, 다양한 HTTP 메서드를 지원하며 요청과 응답에 대한 세밀한 제어를 할 수 있다.
URI uri = UriComponentsBuilder.fromHttpUrl("https://example.com")
.queryParam("authkey", "xxxxxxxxxxxxxxxxxxxxxxxx")
.queryParam("data", "test")
.build()
.encode()
.toUri();
// Request Header 제어
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer token xxxxxxxxxxx");
HttpEntity<String> request = new HttpEntity<>(headers);
// HTTP 메서드 지정
// Response Body Type 지정
ResponseEntity<Member> response = restTemplate.exchange(uri, HttpMethod.POST, request, Member.class);
// Response Header와 Response Body 확인
HttpStatus responseStatus = response.getStatusCode();
HttpHeaders responseHeaders = response.getHeaders();
Member responseBody = response.getBody();
RestTemplate은 4xx, 5xx의 응답 코드를 받았을 때 Exception을 발생시킨다.
개발을 하다보면 4xx, 5xx의 결과 코드도 받아서 처리해야 하는 경우가 있다.
이때 처리할 수 있는 방법에 대해 정리하고자 한다.
RestTemplate은 기본적으로 ResponseErrorHandler interface의 구현체인 DefaultResponseErrorHandler를 사용하여 에러 처리를 하고 있다.
DefaultResponseErrorHandler.java
public class DefaultResponseErrorHandler implements ResponseErrorHandler {
...
protected boolean hasError(int unknownStatusCode) {
HttpStatus.Series series = HttpStatus.Series.resolve(unknownStatusCode);
return (series == HttpStatus.Series.CLIENT_ERROR || series == HttpStatus.Series.SERVER_ERROR);
}
...
protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
String statusText = response.getStatusText();
HttpHeaders headers = response.getHeaders();
byte[] body = getResponseBody(response);
Charset charset = getCharset(response);
String message = getErrorMessage(statusCode.value(), statusText, body, charset);
switch (statusCode.series()) {
case CLIENT_ERROR:
throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset);
case SERVER_ERROR:
throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset);
default:
throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset);
}
}
...
}
statusCode.series()의 값을 확인하여 4xx, 5xx인 경우에 HttpClientErrorException을 던지는 것을 확인할 수 있다.
RestResponseErrorHandler.java
public class RestTemplateErrorHandler extends DefaultResponseErrorHandler{
@Override
public void handleError(ClientHttpResponse response) throws IOException {
HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
//코드별 Custom내용 작성
}
}
RestTemplateConfig.java
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() throws Exception{
RestTemplate restTemplate = new RestTemplate();
...
restTemplate.setErrorHandler(new RestTemplateErrorHandler());
return restTemplate;
}
}
setErrorHandler() 메서드를 통해 직접 생성한 RestErrorHandler를 추가한다.
RestTemplate Example (Open API 사용) / HTTPS SSL 무시 설정 (3) | 2024.09.24 |
---|
댓글 영역