일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 헬름
- ansible
- Spring
- devops
- spring microservice
- 클라우드 네이티브
- 동기화
- 익명클래스
- Stress test
- Adapter 패턴
- 머신러닝
- java
- 코틀린
- Algorithm
- 쿠버네티스
- 자바
- Semaphore
- cloud native java
- ingress
- 마이크로서비스
- Kotlin
- Microservice
- 클라우드 네이티브 자바
- nGrinder
- MySQL
- decorator 패턴
- cloud native
- kubernetes
- MSA
- CRD
- Today
- Total
카샤의 만개시기
RestTemplate 본문
HttpClient는 HTTP를 사용하여 통신하는 범용 라이브러리이고, RestTemplate은 HttpClient 를 추상화(HttpEntity의 json, xml 등)해서 제공해준다. 따라서 내부 통신(HTTP 커넥션)에 있어서는 Apache HttpComponents 를 사용한다.
작동원리
- 어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
- RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
- RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
- ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
- RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
- ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
- RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
- 어플리케이션에 반환된다.
사용법
RestTemplate은 디폴트 생성자 외에 ClientHttpRequestFactory 인터페이스를 받는 생성자가있다. JavaDoc을 참조하면 여러 구현체가 있는데 그 중 SimpleClientHttpRequestFactory
와 HttpComponentsClientHttpRequestFactory
가 대표적인 구현체이다.
RestTemplate restTemplate = new RestTemplate();
별도의 인자 없이 RestTemplate를 생성하게 되면 SimpleClientHttpRequestFactory 구현체를 사용하게 되고 이는 HttpUrlConnection을 이용한다.
또한 다양한 속성을 지원해주지 않으며, connection pool 역시 지원되지 않는다.
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(5000); // 읽기시간초과
factory.setConnectTimeout(3000); // 서버에 연결을 맺을 때의 타임아웃
HttpClient httpClient = HttpClientBuilder.create()
.setMaxConnTotal(100) // 최대 커넥션 갯수
.setMaxConnPerRoute(5) // IP/domain name당 최대 커넥션 갯수
.build();
factory.setHttpClient(httpClient); // 동기실행에 사용될 HttpClient 세팅 RestTemplate restTemplate = new RestTemplate(factory);
connection pool을 적용하기 위해서는 HttpComponentsClientHttpRequestFactor 구현체를 이용하면 되는데 이는 HttpClient 라이브러리를 이용하여 구현되어 있다. HttpClient는 HttpUrlConnection에 비해 모든 응답코드를 읽을 수 있으며, 타임아웃 설정과 쿠키 제어가 가능하다.
Keep-Alive
커넥션 풀은 HTTP에서 미리 연결을 유지하고 있으면서 필요할때 연결되어 있는 커넥션을 이용하여 빠르게 처리하는데 목적이 있다.
하지만 타겟 서버에서 Keep-Alive를 지원하지 않는다면 커넥션 풀은 작동하지 않아, 요청을 할때마다 새로운 커넥션이 연결되어 매번 핸드쉐이크가 발생될것이다.
커넥션 풀을 이용할때는 반드시 타겟 서버에서 Keep-Alive를 지원하는지 확인해야한다.
예외 처리
기본적으로 RestTemplate 은 HTTP 오류가 발생하면 RestClientResponseException
의 확장인 다음 예외 중 하나를 throw합니다.
- HttpClientErrorException : HTTP 상태 4xx의 경우
- HttpServerErrorException : HTTP 상태 5xx의 경우
- UnknownHttpStatusCodeException : 알려지지 않은 HTTP 상태의 경우
ResponseErrorHandler
를 구현하여 적용하면 재사용 가능한 오류 처리기를 구현할수 있습니다.
@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();
}
}
}
}
RestTemplateBuilder
를 사용하여 템플릿을 작성하고 response flow에서 DefaultResponseErrorHandler
를 대체한다.
@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);
}
}
비동기 처리
RestTemplate 는 동기처리에 사용되며 비동기 처리는 org.springframework.web.client.AsyncRestTemplate 를 사용해야 한다.
추가 참조
https://medium.com/@circlee7/resttemplate-host-header-e30596ab04dd
참조
'Java > Spring' 카테고리의 다른 글
JPA에서 Optimistic Lock과 Pessimistic Lock (0) | 2019.07.08 |
---|---|
Spring AOP, Proxy (0) | 2019.07.04 |