[Spring] WebClient 사용 예제

ITWeb/개발일반 2020. 4. 9. 17:01

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

- retrieve()
Perform the HTTP request and retrieve the response body.
This method is a shortcut to using exchange() and decoding the response body through ClientResponse.

- exchange()
Perform the HTTP request and return a ClientResponse with the response status and headers. You can then use methods of the response to consume the body

 

https://spring.io/guides/gs/reactive-rest-service/

 

[Non Blocking]

// retrieve() 예제
  @Override
  public void runner() {
    Mono<String> response = WebClient
        .create(watcherEndpointHost)
        .method(HttpMethod.POST)
        .uri(watcherEndpointUri)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
        .acceptCharset(Charset.forName("UTF-8"))
        .body(BodyInserters.fromValue(getCheckQuery()))
        .retrieve()
        .bodyToMono(String.class);

    response.subscribe(result -> {
      logger.debug("{}", result);
    }, e -> {
      logger.debug("{}", e.getMessage());
    });
  }
  
// exchange() 예제  
  @Override
  public void runner() {
    Mono<String> response = WebClient
        .create(watcherEndpointHost)
        .method(HttpMethod.POST)
        .uri(watcherEndpointUri)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
        .acceptCharset(Charset.forName("UTF-8"))
        .body(BodyInserters.fromValue(getCheckQuery()))
        .exchange()
        .flatMap(clientResponse -> clientResponse.bodyToMono(String.class));

    response.subscribe(result -> {
      logger.debug("{}", result);
    }, e -> {
      logger.debug("{}", e.getMessage());
    });
  }

 

[Blocking]

  @Override
  public void runner() {
    String response = WebClient
        .create(watcherEndpointHost)
        .method(HttpMethod.POST)
        .uri(watcherEndpointUri)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
        .acceptCharset(Charset.forName("UTF-8"))
        .body(BodyInserters.fromValue(getCheckQuery()))
        .exchange()
        .block()
        .bodyToMono(String.class)
        .block();

    logger.debug("{}", response);
  }
  
  @Override
  public void runner() {
    Mono<String> response = WebClient
        .create(watcherEndpointHost)
        .method(HttpMethod.POST)
        .uri(watcherEndpointUri)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
        .acceptCharset(Charset.forName("UTF-8"))
        .body(BodyInserters.fromValue(getCheckQuery()))
        .retrieve()
        .bodyToMono(String.class);

    String result = response.block();
    
    logger.debug("{}", result);
  }

 

WebClient  는 기본 async 방식으로 동작 합니다.

그리고 어디선가 문서에서 봤는데 Connection Pool 관련 고민을 하지 않고 사용해도 된다고 했던 것으로 기억 합니다.

구글링 하다 걸린 코드 걸어 둡니다.

 

[Timeout 설정]

// TcpClient 이용
TcpClient tcpClient = TcpClient.create()
                 .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000) // Connection Timeout
                 .doOnConnected(connection ->
                         connection.addHandlerLast(new ReadTimeoutHandler(10)) // Read Timeout
                                   .addHandlerLast(new WriteTimeoutHandler(10))); // Write Timeout
WebClient webClient = WebClient.builder()
    .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
    .build();


// ReactorClientHttpConnector 이용
ReactorClientHttpConnector connector =
            new ReactorClientHttpConnector(options ->
                    options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000));
WebClient webClient = WebClient.builder().clientConnector(connector).build();

 

보시면 아시겠지만 방법은 다양하게 많이 있습니다.

직관적이고 이해 하기 쉬운 방법을 찾아서 사용하시면 될 것 같습니다.

 

: