【问题标题】:Spring Webflux WebClientSpring Webflux WebClient
【发布时间】:2018-05-09 01:13:32
【问题描述】:

我真的不知道如何正确地将以下调用转换为 spring webflux webclient。

userIds 是列表,我可以使用以下语法调用该服务,但我无法使用 Spring WebFlux WebClient 进行调用。如果有谁知道怎么做,请帮助我。

String url = "http://profile.service.com/v1/profiles/bulk";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

ResponseEntity<List<MiniProfile>> responseEntity;
try {
    responseEntity = restTemplate.exchange(url, HttpMethod.POST, new 
    HttpEntity(userIds, headers), new 
    ParameterizedTypeReference<List<MiniProfile>>() {});
} catch (RestClientException e) {
    responseEntity = new ResponseEntity<List<MiniProfile>>(HttpStatus.OK);
}

return responseEntity.getBody();

这是我将它转换为 Webflux WebClient 的方式:

Flux<String> flux = Flux.fromIterable(userIds);
return readWebClient.post().uri("/v1/profiles/bulk")
      .body(BodyInserters.fromPublisher(flux, String.class))
      .retrieve().bodyToFlux(MiniProfile.class);

【问题讨论】:

  • 您当前的解决方案有什么问题?你得到什么结果?你期待的是什么?
  • 我收到一个 500 错误代码,我不知道它来自哪里,这里是堆栈跟踪。 org.springframework.web.reactive.function.client.WebClientResponseException:ClientResponse 有错误的状态代码:500 内部服务器错误。我希望我们的服务返回一个配置文件列表。请注意带有 RestTemplate 的旧代码对我来说效果很好。
  • 这是属于您的问题的重要信息,真的。这表示服务器使用 HTTP 500 进行响应。因此 RestTemplate 和 WebClient 之间的请求必须不同。
  • 我同意 RestTemplate 和 WebClient 之间的请求必须不同。我一直在尝试查看它们之间的请求是否不同,但我只能看到 RestTemplate 的请求正文被翻译为这样的字符串数组 ["0449b652-0006-0000-0000-000000000000", "0333b652- 0006-0000-0000-000000000000"] 与我们的依赖服务配合得很好,但我无法将 Netty WebClient 中的请求视为像 RestTemplate 这样的 json 格式,所以我不知道有什么区别。你知道如何在 Netty WebClient 中看到序列化的请求正文吗?
  • 您可以像这样设置日志记录级别:logging.level.reactor.ipc.netty.channel.ContextHandler=debug logging.level.reactor.ipc.netty.http.client.HttpClient=debug 在您的application.properties 文件中

标签: spring-boot spring-webflux


【解决方案1】:

您不应该将您的列表更改为flux,您应该像这样将其作为列表发送

return readWebClient.post()
  .uri("/v1/profiles/bulk")
  .syncBody(userIds)
  .retrieve()
  .bodyToFlux(new ParameterizedTypeReference<List<MiniProfile>>() {})
  .flatMapIterable(Function.identity());

此代码未经测试,但原理相同

【讨论】:

  • 感谢您抽出宝贵时间回答我的问题,但您的代码或我的代码没有任何问题,但当我们使用 Webflux Webclient 在 .NET 堆栈上放置或发布时,真正的问题出在我们的 .NET 堆栈上我们需要在 .NET 堆栈中处理原始请求。
【解决方案2】:

使用.bodyValue(userIds).syncBody(userIds)(已弃用)代替带有主体插入器的主体

【讨论】:

    【解决方案3】:

    **你可以参考下面提到的代码sn-ps **

    WebClient.post().uri(endPointUrl)
               .contentType(MediaType.APPLICATION_XML)
              .body(Mono.just(xmlEntity), String.class)
              .retrieve()
    

    【讨论】:

      【解决方案4】:

      最好使用 WebClient 进行这样的响应式调用。

      @Autowired
      private WebClient.Builder webClientBuilder;
      
      webClientBuilder.build().post()
                      .uri("http://profile.service.com/v1/profiles/bulk")
                      .body(BodyInserters.fromPublisher(Mono.just(new YourBodyClass()),YourBodyClass.class))
                      .headers(httpHeaders -> {
                          httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                          httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
                      })
                      .retrieve().bodyToFlux(MiniProfile.class);
      

      【讨论】:

        猜你喜欢
        • 2018-08-18
        • 1970-01-01
        • 2017-12-31
        • 2021-08-06
        • 2019-12-28
        • 1970-01-01
        • 2021-09-10
        • 2017-08-25
        • 2019-04-13
        相关资源
        最近更新 更多