如何在 Spring 集成中使用 webClient?

How to use webClient in Spring Integration?

我正在尝试在我的 Spring 集成应用程序中使用 webClient。 使用 block() 方法我得到了这个错误:

org.springframework.messaging.MessageHandlingException: error occurred during processing message in 'MethodInvokingMessageProcessor' [org.springframework.integration.handler.MethodInvokingMessageProcessor@28b67bb]; nested exception is java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-4
    at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:192) ~[spring-integration-core-5.4.5.jar:5.4.5]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:

所以我删除了 block 以防止出现此问题,但我看起来没有它就无法执行调用。我不知道它是如何工作的

激活剂

@ServiceActivator(
    inputChannel = "lisContractValidationChannel",
    outputChannel = "aopContractValidationReplyAndContinueRouterChannel"

)
public Application sendEContract(Application application) {
    
    ContractRequest contractRequest = prepareRequest(application);
    
    lisOperations.verifyContract(contractRequest,
        application.getContractData().getRouteOne().getConversationID(),
        application.getRouteOneId());
    
    return application;
}

操作

private final WebClient webClient;

@Override
public void verifyContract(
    EContractRequest contractRequest,
    String vendorTransactionId,
    String loanId) {

    
    webClient.post()
        .uri(baseUrl + contract)
        .header("sourceRequestId", sourceRequestId)
        .header("VENDOR-ID", String.join(";", List.of(vendorId, vendorTransactionId, loanId)))
        .bodyValue(contractRequest).retrieve().toEntity(LisResponse.class);
} 

网络客户端配置

@Bean
public WebClient webClient(MetricsDTWebClientFilterFunction metricsDTWebClientFilterFunction) {
    
    HttpClient httpClient = HttpClient
        .create();
    
    final WebClient.Builder webClientBuilder = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .codecs(ClientCodecConfigurer::defaultCodecs)
        .filter(metricsDTWebClientFilterFunction);
    
    return webClientBuilder.build();
}

webClient 是反应组件,任何 Reactive Streams 解决方案都需要订阅才能执行。更重要的是,建议以非阻塞方式执行它们。这就是为什么您使用 block() 运算符时出现 Block Hound 错误的原因。

因为 toEntity() returns 一个 Mono 对我们来说你可以简单地使用它的 subscribe() 来启动请求执行。它可能会立即从您的 verifyContract() 退出,尽管只是因为执行可能发生在不同的线程上。

通过这种方式,您可以考虑将 verifyContract() 的合同更改为 Mono 以将其传播到下游以便在他们的调用中订阅。

请了解有关 Project Reactor 的更多信息,让您自己熟悉所有这些阻塞和非阻塞的东西:https://projectreactor.io/