如何使用 Spring 集成流程处理异常

How to handle Exceptions with a Spring Integration Flow

我正在尝试使用 spring 集成来执行以下操作。

我想从输入通道读取传入的消息,该消息会抛出一系列步骤并产生最终的 message.Each 步骤可能会抛出异常。这可能是由于数据库调用或 ExternalCall 等引起的。每个步骤都被视为服务激活器。如果一切顺利,最终消息是 generated.I 需要将每个步骤抛出的每个异常作为单独的案例处理,然后生成适当的最终消息。

使用下面的 xml 我已经编写了一个测试代码,它在成功时通过了,但是当发生错误时,尽管我看到在通道'bean [=47 上的 postSend (sent=true) 中生成了最终消息=] 记录但进程没有 return 到最终队列。

为什么会这样?

<?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" />

我的处理程序代码如下所示..

@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;
}}

我不确定这是否是错误处理的正确方法。最初的链条是简单的激活器,但在更远的地方会有更多的逻辑。 我们是否应该始终使用链来处理单独的错误通道

  1. 即使调用了单个激活器服务。
  2. 只有当有多个service-activator/transforms封装单点错误时才会出现?

编辑 1 我添加了一个 request-handler-advice-chain 引用一个 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>

引用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>

如果我添加 <property name="onFailureExpression" value="#payload"/> 属性 它会失败:

Cannot convert value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onFailureExpression' 我想做的是将异常消息转换为最终消息对象?但是我添加的所有表达式似乎都无法加载。

只有一个组件的链没有意义。

链只是语法糖,每个组件在运行时仍然独立。

如果您想处理单个端点的错误,请考虑改用 ExpressionEvaluatingRequestHandlerAdvices。

https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/messaging-endpoints.html#message-handler-advice-chain