Spring Webflux WebClient
Posted
技术标签:
【中文标题】Spring 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
文件中
【参考方案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);
【讨论】:
以上是关于Spring Webflux WebClient的主要内容,如果未能解决你的问题,请参考以下文章
Spring Webflux - 03 Webflux编程模型
Spring-WebFlux使用,一文带你从0开始学明白Spring-WebFlux,学明白响应式编程