[英]How to handle Exceptions with a Spring Integration Flow
I am trying to do the following using spring integration.我正在尝试使用 spring 集成来执行以下操作。
I would like to read from an input channel an incoming Message that goes throws a series of Steps and produces a final message.Each step can throw an Exception.我想从输入通道读取传入消息,该消息会引发一系列步骤并生成最终消息。每个步骤都可以引发异常。 This could be either due to a DB call or ExternalCall etc. Each step is considered as a service-activator.
这可能是由于 DB 调用或 ExternalCall 等。每个步骤都被视为服务激活器。 If all is well a successful a final Message is generated.I need to handle each Exception thrown by each Step as a separate case and then produce the appropriate final Message.
如果一切顺利,则生成最终消息。我需要将每个步骤抛出的每个异常作为单独的情况处理,然后生成适当的最终消息。
Using the below xml I have written a test code that passes when sucessfull but when an error occurs although I see a Final message generated in the postSend (sent=true) on channel 'bean 'finalChannel' log but the process does not return to the final queue.使用下面的 xml,我编写了一个测试代码,该代码在成功时通过,但是当发生错误时,虽然我看到在 postSend (sent=true) 通道 'bean'finalChannel' 日志中生成的最终消息,但该过程不会返回到最后的队列。
Why does this happen?为什么会发生这种情况?
<?xml version="1.0" encoding="UTF-8"?>
<context:component-scan base-package="com.demo.">
</context:component-scan>
<header-enricher input-channel="inputChannel"
output-channel="enrichedChannel">
<header name="initialMessage" expression="getPayload()" />
</header-enricher>
<!-- first-step -->
<service-activator input-channel="enrichedChannel"
output-channel="firstStep" ref="validateOne" />
<gateway id="validateOne" default-request-channel="ch1"
error-channel="errors1" />
<chain input-channel="ch1">
<service-activator id="mockServiceOneActivator"
ref="mockServiceOne" method="register" />
</chain>
<!-- enrich-header with payload to be available down the line -->
<header-enricher input-channel="firstStep"
output-channel="secondStep">
<header name="initialInfo" expression="getPayload()" />
</header-enricher>
<!-- second-step -->
<service-activator input-channel="secondStep"
output-channel="enrichWithTwoChannel" ref="validateTwo" />
<gateway id="validateTwo" default-request-channel="ch2"
error-channel="errors2" />
<chain input-channel="ch2">
<service-activator id="mockServiceTwoActivator"
ref="mockServiceTwo" method="callExternal" />
</chain>
<!-- enrich-header with payload to be available down the line -->
<header-enricher input-channel="enrichWithTwoChannel"
output-channel="eligibilityCheck">
<header name="serviceTwoInfo" expression="getPayload()" />
</header-enricher>
<!-- final-step -->
<service-activator input-channel="eligibilityCheck"
output-channel="finalChannel" id="mockServiceFinalActivator"
ref="mockServiceFinal" method="submit" />
<!-- error handling -->
<service-activator input-channel="errors1"
output-channel="finalChannel" ref="traceErrorHandler"
method="handleFailedTrace" />
<service-activator input-channel="errors2"
output-channel="finalChannel" ref="traceErrorHandler2"
method="handleFailedTrace" />
<channel id="finalChannel">
<queue />
</channel>
<service-activator input-channel="errorChannel"
ref="globalExceptionHandler" method="handleError" />
My handler code looks like this ..我的处理程序代码看起来像这样..
@Component("traceErrorHandler")public class TraceErrorHandler {
public Message<FinalMessage> handleFailedTrace(Message<?> errorMessage) {
MessagingException payload = (MessagingException) errorMessage.getPayload();
InitialMessage im = (InitialMessage) payload.getFailedMessage().getHeaders().get("initialMessage");
ServiceOneException error = (ServiceOneException) payload.getCause();
FinalMessage v = new FinalMessage(im.getFrom(), im.getTo(), error.getErrorTemplate());
Message<FinalMessage> finalMessage = MessageBuilder.withPayload(v).copyHeaders(payload.getFailedMessage().getHeaders()).build();
return finalMessage;
}}
I am not sure if this is the correct approach in regards to error-handling.我不确定这是否是处理错误的正确方法。 The initial chains are simple activators but further down the line there will be more logic.
最初的链是简单的激活器,但进一步向下会有更多的逻辑。 Should we I always use chains to handle separate error channels
我们是否应该总是使用链来处理单独的错误通道
EDIT 1 I added a request-handler-advice-chain reference a bean.编辑 1我添加了一个请求处理程序建议链引用一个 bean。
<int:service-activator
id="serviceOneActivator" input-channel="enrichedChannel"
ref="serviceOne" method="register" output-channel="firstStep">
<int:request-handler-advice-chain>
<ref bean="myclass" />
</int:request-handler-advice-chain></int:service-activator>
The reference bean is at first a default definition in xml引用 bean 首先是 xml 中的默认定义
<bean id="myclass"
class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
<property name="failureChannel" ref="finalChannel" />
<property name="onFailureExpression" value="#payload"/>
<property name="returnFailureExpressionResult" value="true" />
</bean>
if I add the <property name="onFailureExpression" value="#payload"/>
property it fails with:如果我添加
<property name="onFailureExpression" value="#payload"/>
属性,它会失败:
Cannot convert value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onFailureExpression'
What i would like to do is convert the exception message to a final message object? Cannot convert value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onFailureExpression'
我想做的是将异常消息转换为最终消息对象? but all expression i have added seem to fail on load.但是我添加的所有表达式似乎在加载时都失败了。
A chain with one component makes no sense.一个只有一个组件的链是没有意义的。
A chain is syntactic sugar only, each component still stands alone at runtime.链只是语法糖,每个组件在运行时仍然是独立的。
If you want to handle errors for individual endpoints, consider using ExpressionEvaluatingRequestHandlerAdvice
s instead.如果要处理单个端点的错误,请考虑改用
ExpressionEvaluatingRequestHandlerAdvice
。
See https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/messaging-endpoints.html#message-handler-advice-chain请参阅https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/messaging-endpoints.html#message-handler-advice-chain
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.