티스토리 뷰

BackEnd/SpringBoot

[Spring] - RestTemplate 개념

영지는 달리는중 2021. 6. 16. 11:05

HTTP 서버와의 통신방법

 

  • URLConnection

 jdk 1.2 부터 내장되어 있으며, java.net 패키지에 있다. URL의 내용을 읽어오거나, URL 주소에 GET, POST로 데이터를 전달 할 때 사용한다.

또한 http 프로토콜 이외에도 가능하다.(file 등) 

주요 메소드

new URL("http:// ....")
openConnection()
URLConnection
getInputStream, getOutputStream
InputStream, OutputStream 처리

          1.  응답코드가 4xx, 5xx 이면 IOException이 터진다

          2. 타임아웃을 설정할 수 없다

          3. 쿠키 제어가 불가하다

 

  • HttpClient

4.x부터는 Apache HttpComponents 로 불린다.

maven dependency 를 설정하거나, http://hc.apache.org/downloads.cgi 에서 다운로드할 수 있다. org.apache.http 패키지에 있다.

URLConnection과 달리 모든  응답코드를 읽을 수 있고, 타임아웃 설정과 쿠키 제어가 가능하다.

주요 메소드

CloseableHttpClient httpclient = HttpClients.createDefault();
new HttpGet("http:// ....");
CloseableHttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
Stream으로 entity.getContent() 처리 등

 

      문제점

  1. URLConnection을 이용한 방식보다 코드가 간결해졌지만 여전히 반복적인 코드들이 많다
  2. 스트림 처리 로직을 별도로 짜야한다
  3. 응답의 컨텐츠 타입에 따라 별도의  로직이 필요하다. 

 

  • WebClient 

Spring 5부터 동기, 비동기 방식을 둘다 지원하는 클래스이다. 

RestTemplate란

스프링에서 제공하는 HTTP Client REST API 호출을 위한 함수를 제공하는 클래스이다.

 

      특징

  1. Spring 3부터 지원, Blocking I/O에 의존하며 동시 방식으로 작동된다
  2. Srping 4부터는 비동기 방식으로 작동하는 AsyncRestTemplate을 지원한다 

 

주요 메소드 

execute
exchange
getForObject

등 여러가지가 있다. 보통은 모든 Http Method를 처리할 수 있는 exchange 메소드를 가장 많이 사용한다. 

 

동작원리 


 

  • 어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
  • RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
  • RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
  • ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
  • RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
  • ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
  • RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
  • 어플리케이션에 반환된다.

 

RestTemplate에서의 HttpClient

RestTemplate은 RESTful HTTP request를 만드는 추상화를 제공하며, 내부적으로 RestTemplate은 이러한 요청을 보내기 위해 native HttpClient을 사용한다.

기본 생성자로 RestTemplate를 생성하면, HttpURLConnection 객체를 사용해서 요청을 보낸다. 만약에 다른 HTTP 라이브러리를 사용하고 싶다면, ClientHttpRequestFactory 구현체를 RestTemplate의 생성자로 넘겨주면 된다.

예를 들어 apache에서 제공하는 HttpClient를 사용해서 요청을 보내고 싶다면, HttpComponentsClientHttpRequestFactory 객체를 RestTemplate의 생성자로 넘겨주면 된다. 또는 setRequestFactory(ClientHttpRequestFactory requestFactory) 메소드로

HttpComponentsClientHttpRequestFactory 객체를 설정해주면 된다.

 

Connection Pool 사용하기

RestTemplate을 기본 생성자로 생성하는 경우, ClientHttpRequestFactory 구현체로 SimpleClinetHttpRequestFactory를 사용한다. SimpleClinetHttpRequestFactory는 REST API를 호출할 때마다, HttpURLConnection 객체를 생성한다.

즉 소켓을 재사용하지 않고, 요청을 보낼때마다 새로운 소켓 연결을 시도한다. 따라서 외부 호출이 많은 서비스에서 RestTemplate을 사용한다면, 반드시 connection pooling을 해야한다. connection pooling을 위해서 아래와 같이 RestTemplate을 생성하면 된다.

public void init() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setReadTimeout(10000);
    factory.setConnectTimeout(10000);
     
    HttpClient httpClient = HttpClientBuilder.create()
                                .setMaxConnTotal(50)
                                .setMaxConnPerRoute(20).build();
    factory.setHttpClient(httpClient);
    restTemplate = new RestTemplate(factory);
}
  • maxConnPerRoute : 단일 IP:PORT 쌍에 대한 커넥션의 수를 제한
  • maxConnTotal : 총 커넥션 수를 제한

 

 + 추가 정보

스프링 프레임워크에서 제공하는 HTTP 클라이언트 템플릿인 RestTemplate 클래스는 객체 생성 시 내부에 무거운 Charset.availableCharsets 메서드가 실행된다.

더구나 Charset.availableCharsets 메서드는 여러 스레드가 동시에 사용했을 때 스레드 간에 락 경합이 생겨서 급격한 성능 저하를 유발한다.

 RestTemplate은 스레드 간에 공유해도 안전한 클래스이므로 싱글턴 구조로 객체를 한 개만 생성한 후 스레드 간에 공유해서 사용하도록 수정한다.

RestTemplate 클래스를 스프링 프레임워크의 빈으로 사용할 수도 있으나 RestTemplate 클래스를 사용하는 MobileClient 클래스 또한 프레임워크의 일부라서 빈 대신 static을 사용한 싱글턴 구조를 만드는 것을 추천한다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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 31
글 보관함