如何返回包含 Reactive Mono 和 Flux 的 Reactive Flux?

Dar*_*erM 1 java spring spring-webflux spring-webclient

我是反应式编程的新手,遇到了这个问题:

[
    {
        "customerDTO": {
            "scanAvailable": true
        },
        "bankAccountDTOs": {
            "scanAvailable": true,
            "prefetch": -1
        }
    }
]
Run Code Online (Sandbox Code Playgroud)

数据传输对象:

public class ResponseClientDTO {
    private Mono<CustomerDTO> customerDTO;
    private Flux<BankAccountDTO> bankAccountDTOs;
}
Run Code Online (Sandbox Code Playgroud)

服务:

public Flux<ResponseClientDTO> getCustomerWithBankAccounts(String customerId){
    Flux<BankAccountDTO> bankAccounts = webClient
        .get()
        .uri(uriBuilder -> 
                uriBuilder.path("customers")
                .queryParam("customerId", customerId).build())
        .accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .bodyToFlux(BankAccountDTO.class);
        
    
    Mono<CustomerDTO> cMono = findOne(customerId);
    
    ResponseClientDTO responseClientDTO = new ResponseClientDTO();
    responseClientDTO.setBankAccountDTOs(bankAccounts);
    responseClientDTO.setCustomerDTO(cMono);
    
    return Flux.just(responseClientDTO);
}
Run Code Online (Sandbox Code Playgroud)

我从另一个 API 查询端点,它返回一个Flux<BankAccounts>. 我想找到客户所有的银行账户。

Joã*_*ias 7

这不是您在反应式堆栈中想要的。首先,更改您的 DTO(数据传输对象),使其不包含Monoand Flux,而是包含CustomerDTOand List<BankAccountDTO>

public class ResponseClientDTO {
    private CustomerDTO customerDTO;
    private List<BankAccountDTO> bankAccountDTOs;
}
Run Code Online (Sandbox Code Playgroud)

然后,您需要重新安排您的方法以返回 aMono<ResponseClientDTO>并更改处理Fluxand的逻辑Mono

public Mono<ResponseClientDTO> getCustomerWithBankAccounts(String customerId){
    Flux<BankAccountDTO> bankAccounts = webClient
        .get()
        .uri(uriBuilder -> 
                uriBuilder.path("customers")
                .queryParam("customerId", customerId).build())
        .accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .bodyToFlux(BankAccountDTO.class);
        
    Mono<CustomerDTO> cMono = findOne(customerId);
    
    return bankAccounts.collectList().zipWith(cMono).map(data -> {
        ResponseClientDTO responseClientDTO = new ResponseClientDTO();
        responseClientDTO.setBankAccountDTOs(data.getT1());
        responseClientDTO.setCustomerDTO(data.getT2());
    })
}
Run Code Online (Sandbox Code Playgroud)

(对于任何 Java 拼写错误,我深表歉意,但此时我已经习惯了 Kotlin)。

考虑查看以下有用的在线资源: