简体   繁体   English

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

[英]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我们是否应该总是使用链来处理单独的错误通道

  1. Even if its a single activator service called.即使它调用了单个激活器服务。
  2. Only when there are Multiple service-activator/transforms that encapsulate a single point of error?仅当存在多个封装单点错误的服务激活器/转换时?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM