Spring Webflux WebClient

3

我不太清楚如何正确翻译以下对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);

你当前的解决方案有什么问题?你得到了什么结果?你本来期望得到什么? - Brian Clozel
1
我遇到了一个500错误码,但我不知道它来自哪里,以下是堆栈跟踪信息。org.springframework.web.reactive.function.client.WebClientResponseException: ClientResponse has erroneous status code: 500 Internal Server Error。 我期望我们的服务返回一个配置文件列表。请注意,旧的RestTemplate代码对我来说运行良好。 - Eric Nguyen
这是一个非常重要的信息,应该包含在你的问题中。这意味着服务器响应了HTTP 500。因此,RestTemplate 和 WebClient 之间的请求必须不同。 - Brian Clozel
我同意RestTemplate和WebClient之间的请求必须不同。我一直在尝试查看它们之间的请求是否不同,但我只能看到RestTemplate的请求正文被翻译为字符串数组,如["0449b652-0006-0000-0000-000000000000","0333b652-0006-0000-0000-000000000000"],这对我们的依赖服务很好用,但是我无法像RestTemplate那样在Netty WebClient中看到请求的json,因此我无法确定差异在哪里。您有任何想法如何在Netty WebClient中查看序列化请求正文吗? - Eric Nguyen
您可以在application.properties文件中设置日志级别,例如:logging.level.reactor.ipc.netty.channel.ContextHandler=debuglogging.level.reactor.ipc.netty.http.client.HttpClient=debug - Brian Clozel
@BrianClozel 在添加了调试级别之后,大部分日志看起来像是TCP转储。有没有办法在日志文件中将正文以文本形式查看? - Ashok Koyi
4个回答

1
你不应该将列表更改为流,而应该像这样发送它作为列表。
return readWebClient.post()
  .uri("/v1/profiles/bulk")
  .syncBody(userIds)
  .retrieve()
  .bodyToFlux(new ParameterizedTypeReference<List<MiniProfile>>() {})
  .flatMapIterable(Function.identity());

这段代码未经测试,但原理相同。


感谢您抽出时间回答我的问题,但是您的代码和我的代码都没有问题,真正的问题在于我们的.NET堆栈。当我们使用Webflux Webclient在.NET堆栈上进行PUT或POST时,我们需要在.NET堆栈中处理原始请求。 - Eric Nguyen

1

使用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);

0

**你可以参考下面提到的代码片段**

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

0
使用 .bodyValue(userIds).syncBody(userIds)(已弃用)代替带有 Body inserter 的 body。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接