java - 使用 WebClient/Spring Boot 2 将 REST 响应映射到 Mono<SomeClass> 的正确方法

标签 java spring project-reactor reactive spring-webclient

我有一个 Controller ,它要求服务到达服务端点以获取帐号列表,然后为每个帐号联系另一个服务并检索有关该帐户的其他数据。 “幸福之路”本质上是这样的:

Controller

@ApiOperation(value = "getRelatedAccounts")
@GetMapping(value = "/relatedaccounts")
public ResponseEntity<RelatedAccounts> getRelatedAccounts(@RequestParam String accountNumber) {
    return new ResponseEntity<>(myService.getRelatedAccounts(accountNumber), HttpStatus.OK);
}

服务

public RelatedAccounts getRelatedAccounts(String accountNumber) {
    // blah blah, hit the endpoint and get my response of a list of account numbers in relatedAccountsList
    Flux<AccountInformation> accountInfoFlux = Flux.fromIterable(relatedAccountsList)
        .parallel()
        .runOn(Schedulers.elastic())
        .flatMap(this::getAccountInformation)
        .ordered(Comparator.comparing(RelatedAccounts::getCorrectOrder)) // blah blah, convert from ParallelFlux to Flux
}

其他服务

public Mono<AccountInformation> getAccountInformation(String accountNumber) {
    WebClient webClient = WebClient.builder()
            .baseUrl("http://myurl.com")
            .build();

    return webClient
            .get()
            .uri(uriBuilder -> uriBuilder
                    .queryParam("accountNumber", accountNumber)
                    .build()
            ).retrieve()
            .bodyToMono(AccountInformation.class) // This doesn't work for us, we get a very complex object as a response and need to parse a few fields.
}

我在 Google 上花了一整天的时间,没有看到其他人解析他们返回的响应,他们只是神奇地将其直接映射到完美创建的类上。我们没有这个选项,我们需要从响应正文中提取 accountName 并将其放入 AccountInformation 对象中。有人知道如何做到这一点吗?

最佳答案

我的建议是继续使用 bodyToMono(AccountInformation.class),然后使用 Monos map 映射到您的简单对象。和 zip .

  1. 创建一个表示复杂 AccountInformation 的类,但仅包含您需要的信息(不包含您不需要的对象字段)。
  2. 使用其他服务的确切代码(返回 Mono)
  3. 您可以使用 .zip 将简单对象与 AccountInformation 对象组合起来。
  4. 因此,您将获得简单对象,其中仅包含复杂对象所需的数据

例如。

其他服务保持不变:

public Mono<AccountInformation> getAccountInformation(String accountNumber) {
    WebClient webClient = WebClient.builder()
            .baseUrl("http://myurl.com")
            .build();

    return webClient
            .get()
            .uri(uriBuilder -> uriBuilder
                    .queryParam("accountNumber", accountNumber)
                    .build()
            ).retrieve()
            .bodyToMono(AccountInformation.class)
}

创建缺少的类(代表其他服务的结果),跳过您不需要的信息的所有字段

import java.util.List;

public class AccountInformation {
    private String infoYouWant;
    private List<AccountDetails> otherNestedInfoYouWant;
// getters/setters skipped for easier read
}

将您的简单对象与其他服务中的对象合并:

        Mono<AccountInformation> accountInformation = someService.getAccountInformation("fillMeWithAccountNumber");
        Mono<SimpleObject> simpleObjectWithAccountInformation = Mono.zip(simpleObject, accountInformation).map(objects -> {
            SimpleObject simpleObject = objects.getT1();
            simpleObject.setAccountNumber(objects.getT2().getInfoYouWant());
            return simpleObject;
        });

关于java - 使用 WebClient/Spring Boot 2 将 REST 响应映射到 Mono<SomeClass> 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68777094/

相关文章:

java - 调整 JPopupMenu 的大小并避免 "flicker"问题

java - JVM 可以看到多少代码?

java - 使用文本文件中的数据创建重定向链接

java - 无法创建 SAAJ 元工厂 : Provider com. sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl not found

java - react 堆: function creating Monos to Flux

java - 将 SlidingPaneLayout 的触摸事件限制在屏幕的最左边缘

java - SpringMVC + Hibernate Tomcat 500,json 无堆栈跟踪

java - 将通量拆分为两个通量 - 头和尾

java - 是否建议将Arraylist转换为Reactor的flux来处理数据?

java - WSDL 操作中的soapAction 属性为空