如何在 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/
我正在尝试在我的 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/