Java 异步流中出站网关上的错误处理
我有一个这样的集成流程:Java 异步流中出站网关上的错误处理,java,spring-integration,Java,Spring Integration,我有一个这样的集成流程: @Bean public IntegrationFlow inboundRequestFlow() { return IntegrationFlows.from( inboundRequestGateway() ) .log( ... ) .filter( requestValidator, spec -> spec.discardChannel( invalidRequestChannel() )
@Bean
public IntegrationFlow inboundRequestFlow()
{
return IntegrationFlows.from( inboundRequestGateway() )
.log( ... )
.filter( requestValidator,
spec -> spec.discardChannel( invalidRequestChannel() ) )
.bridge( spec -> spec.requiresReply( false ) )
.channel( asyncFlowChannel )
.wireTap(
//sends a NO_CONTENT reply if the request is ok
flow -> flow.enrichHeaders( spec -> spec.header( HttpHeaders.STATUS_CODE, HttpStatus.NO_CONTENT ).defaultOverwrite( true ) )
.transform( payload -> "" )
.channel( inboundGatewayReplyChannel() )
).get();
}
它在http网关上接收请求,对其进行验证,如果一切正常,则将请求发送到“asyncFlowChannel”,并使用204回复入站网关
“asyncFlowChannel”是在执行器通道上运行的另一个IntegrationFlow的起点:
@Bean
public IntegrationFlow outboundFlow()
{
return IntegrationFlows.from( asyncFlowChannel)
.log( ... )
.transform( ... )
.transform( ... )
.split(... )
.resequence( ... )
.enrichHeaders( ... )
.log( ... )
.transform( ... )
.handle( this.outboundSOAPGateway() )
.log( .. )
.handle( ... )
.bridge( spec -> spec.requiresReply( false ) )
.channel( anotherAsyncFlowChannel )
.get();
}
如果outboundGateway出现异常(由于网络相关IO错误或错误响应),我希望记录错误并采取适当措施。但是我不能在outboundSOAPGateway上设置错误通道,启动流上的inboundRequestGateway已经收到它的回复
我得到的唯一错误线索是以下日志:
10:19:53.002警告[outbound-flow-0]org.springframework.messaging.core.GenericMessageTemplate$TemporaryReplyChannel-已收到回复消息,但接收线程已收到回复:ErrorMessage[payload=…,headers=…]
我的问题是:在异步流中,如果启动流的inboundGateway已经收到它的回复,那么处理出站网关错误的正确方法是什么?而不是。通道(asyncFlowChannel)
,使用
.gateway(asyncFlowChannel, e -> e.errorChannel(...))
任何
MessageHandler
端点都可以与AbstractRequestHandlerAdvice
一起提供。其中之一是expressionevaluationrequesthandleradvice
,您可以捕获异常并将其发送到failureChannel
:
为此,.handle(this.outboundSOAPGateway())
可以与第二个参数一起提供,例如:
.handle((GenericHandler<?>) (p, h) -> {
throw new RuntimeException("intentional");
}, e -> e.advice(retryAdvice()))
但这同样适用于表达式evaluationRequestHandlerAdvice
顺便说一句,
retryAdvice()
也可以为您的客户提供帮助。请参阅其ErrorMessageSendingRecoverer
另请参阅我的答案。我尝试了此方法,错误通道被正确调用,但入站网关不再同步响应。。。我还尝试了.gateway(labelRequestInputChannel,spec->spec.errorChannel(failedLabelRequestRecoveryChannel).requiresReply(false)),但它仍然等待流结束,以便回复Yeh yes;抱歉,网关必须跟随执行器通道。但是Artem的建议也很好。我在我的建议链中添加了新的ErrorMessageSendingRecoverer(recoveryChannel()),它成功了。。。谢谢
@Bean
public RequestHandlerRetryAdvice retryAdvice() {
RequestHandlerRetryAdvice requestHandlerRetryAdvice = new RequestHandlerRetryAdvice();
requestHandlerRetryAdvice.setRecoveryCallback(new ErrorMessageSendingRecoverer(recoveryChannel()));
return requestHandlerRetryAdvice;
}