Java & Spring/기타

외부 통신 - (RestTemplate, AsyncRestTemplate, WebClient, HttpURLConnection, HttpClient ) 간략 정리

Zin0_0 2021. 7. 29. 17:11
반응형

RestTemplate

  • Spring 3.0 부터 지원
  • Bolierplate code를 줄여줌
  • RestAPI를 사용해야하는 경우 적합
  • Multi-Thread & Blocking 방식
  • JDK HttpURLConnection, Apache Http Components 등과 같이 기본 HTTP 클라이언트 라이브러리를 통해 템플릿 메서드 API를 제공하는 HTTP 요청을 수행하는 동기식 client
  • RestTemplate은 HTTP 메소드에 대한 시나리오를 제공하고, exchange와 excute 메소드를 제공
    • spring에서 5.0부터는 org.springframework.web.reactive.client를 사용하는 것을 권유
      • 최신 API와 동기, 비동기, 스트리밍 시나리오를 지원

AsyncRestTemplate

  • Spring 4.0 부터 지원 ~> 현재 deprecated
  • 비동기 클라이언트측 HTTP 액세스를 위한 스프링의 중앙 class
  • RestTemplate과 유사하지만, 구체적인 결과는 ListenableFuture 로 래핑되어 반환
  • getRestOperations() 메소드를 통해 동기식 RestTemplate을 노출시키고, Error Handler와 Message Converter를 RestTemplate과 공유

WebClient

  • Spring 5.0 부터 지원
  • HTTP 요청을 수행하기 위한 Non-blocking 방식의 reactive 클라이언트
    • Non-blocking
      • Connection은 유지되지만, 응답이 오기 전까지 다른 작업을 수행하다가 응답이 오면 callback을 수행하는 방식
  • Single-Thread & Non-blocking
  • 각 요청이 event loop에 Job으로 등록되고, event loop가 각 Job을 제공자에게 요청한 후, 결과를 기다리지 않고 다른 Job을 처리
    • callback이 오면 결과를 요청자에게 제공

HttpURLConnection

  • HTTP별 기능을 지원하는 URLConnection
  • 각 HttpURLConnection 인스턴스는 단일 요청을 만드는데 사용
    • HTTP 서버에 대한 기본 네트워크 connection은 다른 인스턴스과 공유 가능
    • 요청 이후 HttpURLConnection의 InputStream이나 OutputStream의 close() 메소드를 호출하면, 인스턴스와 연결된 네트워크 리소스를 확보할 수 있지만, 영속적으로 공유된 connection에는 영향을 미치지 않음
    • disconnect()를 호출하면, 영속적으로 공유된 connection이 놀고있는 소켓을 close시킴
  • response 결과를 직접 stream으로 처리해야하는 등 개발 생산성이 다소 떨어짐

HttpClient

  • Java 11 이전에는 아파치에서 제공하는 라이브러리 사용
  • Java 1부터 java.net 패키지에 http 관련 라이브러리가 추가됨
  • Builder를 통해 생성
    • Builder는 각 client 별 상태(프로토콜 버전(HTTP/1.1 or HTTP/2), ridirect, 프록시, 인증자 등)를 구성할 수 있음
    • build 이후에는 HttpClient는 immutable로 여러 요청을 보내는 데 사용할 수 있음
  • 각 HttpRequest에 대해서 BodyHandler를 제공해야함
    • BodyHandler<T>는 response body를 어떻게 핸들링할지 결정 ~> 응답 받을 형태를 관리
    • HttpResponse를 받아 헤더, response code, body를 사용할 수 있음
  • 동기와 비동기 모두 지원
    • send(HttpRequest, BodyHandler)
    • sendAsync(HttpRequest, Bodyhander)
  • Synchronous Example
  • HttpClient client = HttpClient.newBuilder() .version(Version.HTTP_1_1) .followRedirects(Redirect.NORMAL) .connectTimeout(Duration.ofSeconds(20)) .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80))) .authenticator(Authenticator.getDefault()) .build(); HttpResponse<String> response = client.send(request, BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body());
  • Asynchronous Example
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://foo.com/"))
    .timeout(Duration.ofMinutes(2))
    .header("Content-Type", "application/json")
    .POST(BodyPublishers.ofFile(Paths.get("file.json")))
    .build();
client.sendAsync(request, BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);  

Reference

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/AsyncRestTemplate.html

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.html

https://happycloud-lee.tistory.com/220 <- Spring WebClient에 대한 상세한 설명

http://wonwoo.ml/index.php/post/2364 <- Spring WebClient 예제

https://itforusblog.wordpress.com/2020/05/13/resttemplate-or-httpurlconnection/

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/HttpURLConnection.html

https://digitalbourgeois.tistory.com/56

https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html

https://lts0606.tistory.com/455 <- HttpClient 기본 CRUD 및 multipart예제

반응형