한국의 메타몽 2021. 8. 16. 17:30

 

RestTemplate이란?

 

RestTemplate restTemplate = new RestTemplate();

간편하게 Rest방식의 API를 호출할 수 있는 Spring 내장 클래스다.

Spring 3.0부터 지원이 되며, Json, Xml 응답을 모두 받을 수 있다.

 

 

HTTP 서버와의 통신 방법

 

Client와 Server로 나누어서 먼저 프로젝트를 생성한다.

 

 Server Directory

 

Client Directory

 

참고로 Server는 Port번호를 8080으로, Client는 9090으로 설정했다.

 

아래 방법들은 모두 HTTP 메소드 중 GET을 기반으로 동작한다.

 

(1) Server의 ServerApiController

@RestController
@RequestMapping("/api/server")
public class ServerApiController {
  @GetMapping("/hello")
  public String hello(){
    return "Hello Server!";
  }
}

 

(2) Client의 ApiController

@RestController
@RequestMapping("/api/client")
public class ApiController {
  //@Autowired가 다소 오래된 방법이라 직접 생성자를 만듦
  private final RestTemplateService restTemplateService;

  public ApiController(RestTemplateService restTemplateService) {
    this.restTemplateService = restTemplateService;
  }

  @GetMapping("/hello")
  public String getHello(){
    return restTemplateService.hello();
  }
}

 

(3) Client의 RestTemplateService

@Service
public class RestTemplateService {

  public String hello(){
    URI uri = UriComponentsBuilder
        .fromUriString("http://localhost:9090")
        .path("/api/server/hello")
        .encode()
        .build()
        .toUri();
    System.out.println(uri.toString());

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class); // 가져오겠다는 get이 아니라 HTTP의 GET을 의미함

    System.out.println(result.getStatusCode());
    System.out.println(result.getBody());

    return result.getBody();
  }
}

* UriComponentBuilder : 여러개의 파라미터를 이용하여 URL를 작성할 때에 개발자가 편하게 작성할 수 있도록 도와줌

* getForEntity : 가져오겠다는 get이 아니라 HTTP의 get method

 

위 코드의 실행 순서는 다음과 같다.

  1. localhost:8080/api/client/hello를 호출
  2. restTemplateService.hello()를 반환
  3. restTemplateService.hello()는 localhost:9090/api/server/hello를 호출하여 "Hello Server"를 리턴

 

 

 

번외 : URLConnection vs HttpClient

 

 

(1) URLConnection

Maven으로 RestTemplate을 이용하지 않고 순수하게 Java에서의 Class를 이용해서 HTTP 서버와 연결한다.

기본 JDK에 포함되며, HTTP뿐만 아니라 여러 프로토콜을 제공한다.

// http://www.test.co.kr/test.jsp에 있는 내용을 읽어올거다
URL obj = new URL("http://www.test.co.kr/test.jsp"); // 호출할 url
HttpURLConnection con = (HttpURLConnection)obj.openConnection();
 
con.setRequestMethod("GET");
 
in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
        
String line;
            
while((line = in.readLine()) != null) { // response를 차례대로 출력
      System.out.println(line);
}

위는 예시코드이며, URL의 내용을 읽어오거나 URL 주소에 GET,POST로 데이터를 전달할 때 사용한다.

단점으로 응답코드가 4XX이거나 5XX이면 IOException이 발생하며, 쿠키 제어가 불가능하다.

 

 

(2) HttpClient

org.apache.http.client에서 제공하는 라이브러리이다.

    // http://localhost/api/server/hello에 요청해서
    // response를 받을거다. 반환 타입은 Json이다.

    public UserResponse hello(){
        URI uri = UriComponentsBuilder
                .fromUriString("http://localhost:9090")
                .path("/api/server/hello")
                .encode() // 안전하게 인코딩해서 보내자
                .build()
                .toUri();
        System.out.println(uri.toString());
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<UserResponse> result = restTemplate.getForEntity(uri, UserResponse.class); // 주의. 여기서 get은 HTTP - GET을 뜻한다.

        System.out.println(result.getStatusCode());
        System.out.println(result.getBody());

        return result.getBody();
    }

 

 

실행 결과

 

아래에 기술될 내용처럼, URlConnection에 비해 장점이 많지만 단점도 존재한다.
UrlConnection을 이용한 방식보다 코드가 간결해졌지만 여전히 반복적이고 코드들이 길다.

또한 응답의 컨텐츠 타입에 따라 별도 로직이 필요하다.

 

UrlConnection과  HttpClient의 구체적인 차이점은 다음과 같다.

 

  URL Connection HTTPClient
Methods HEAD, GET, POST, PUT, DELETE, TRACEAND OPTIONS 총합 7개만 존재 왼쪽의 7개 이외에 임의의 메소드들 존재
(ex : WEBDav, IPP)
Response Codes 응답코드 400미만의 body, headers 등을 읽음.
400이상의 응답코드는 IOExcepeiton 발생
상관없이 모두 읽어냄
Proxies and SOCKS 모두 지원 (SOCKS : Version 4 only) 모두 지원 (SOCKS : Version 4 and 5)
Authorization JDK 1.2 이상에서는 Basic 및 이전 버전의 Digest만 지원. 현재 버전의 Digest 인증(대부분 서버에서 지원하는 버전)은 지원되지 않으며, 버그로 인해 Apache에서 반환된 Digest 정보도 인식 불가 Basic 및 Digest 인증 지원. 다른 스키마도 추가 가능
Cookies NO YES
그래서 세션을 유지할떄 HTTP Client를 사용
True request output streams NO - 모든 데이터는 보내지기전에 완전히 버퍼링된다. YES - HttpOutputStream이 직접적으로 소켓에 데이터를 송출한다.
True Respons input stream JDK 1.2이하 버젼에서는 YES.
1.3버젼부터는 NO.
YES
Persistent Connections HTTP/1.0은 JDK1.2와 JDK1.2에서 Keep-alive
JDK1.3은 HTTP/1.1의 지속성을 가짐.
HTTP/1.0은 Keep-alive.
HTTP/1.1은 지속성을 가짐.
Pipelining of requests No Yes
Can set timeouts  No Yes
Can handle protocols other than HTTP Yes
(ex : FTP, File, Malito)
No
Can do HTTP over SSL(https) 적절한 Client를 제공하는 적절한 SSL 패키지를 설치해야함 다양한 무료 및 상용 SSL 패키지를 사용 가능
Source code available No Yes

 

표에서 확인할 수 있듯이 HttpClient가 UrlConnection보다 장점이 많다.

 

 

RestTemplate 동작원리

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

 

RestTemplate 사용하기

 

HttpClient에 사용되느 주요 메소드는 다음과 같다.

Rest Template Method HTTP Method 설명
execute Any Request / Response 콜백을 수정
exchange Any HTTP 헤더를 새로 만들 수 있고 어떤 HTTP 메소드도 사용 가능
getForObject GET 주어진 URL주소로 get 요청을 보내고 객체로 결과를 반환
getForEntity GET 주어진 URL주소로 get 요청을 보내고 ResponseEntity로 
결과를 반환
postForLocation POST post 요청을 보내고 헤더에 저장된 URI를 결과로 반환
postForObject POST post 요청을 보내고 객체로 결과를 반환
postForEntity POST post 요청을 보내고 결과를 ResponseEntity로 반환
put PUT 주어진 URL주소로 put 메소드 실행 
delete DELETE 주어진 주소로 delete 메소드 실행
headForHeaders HEAD 헤더의 모든 정보를 얻을 수 있으므녀 head메소드를 사용
optionsForAllow OPTIONS 주어진 URL 주소에서 지원하는 HTTP메소드를 조회

 

 

참고 출처

 

떡건님 - httpclient와 urlconnection 차이점

 

httpclient와 urlconnection 차이점

HttpClient와 UrlConnection의 차이점은 무엇일까? 왜 세션 유지할때 HttpClient를 이용해서 할까.. ...

blog.naver.com

 

빨간색소년님 - RestTemplate

 

RestTemplate (정의, 특징, URLConnection, HttpClient, 동작원리, 사용법, connection pool 적용)

참조문서 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html 1. RestTemplate이란? spring 3.0 부터 지원한다. 스프링에서 제공하는 http..

sjh836.tistory.com