java - 如何使用 Spring 集成流处理异常
问题描述
我正在尝试使用弹簧集成执行以下操作。
我想从输入通道中读取传入的消息,该消息会引发一系列步骤并产生最终消息。每个步骤都可以引发异常。这可能是由于 DB 调用或 ExternalCall 等造成的。每个步骤都被视为服务激活器。如果一切顺利,则生成最终消息。我需要将每个步骤抛出的每个异常作为单独的案例处理,然后生成适当的最终消息。
使用下面的 xml 我编写了一个测试代码,该代码在成功但发生错误时通过,尽管我在通道 'bean'finalChannel' 日志上的 postSend (sent=true) 中看到了最终消息,但该过程没有返回最后的队列。
为什么会这样?
<?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 我添加了一个 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'
我想做的是将异常消息转换为最终消息对象?但我添加的所有表达式似乎在加载时都失败了。
解决方案
具有一个组件的链没有意义。
链只是语法糖,每个组件在运行时仍然独立。
如果要处理单个端点的错误,请考虑使用ExpressionEvaluatingRequestHandlerAdvice
s 代替。
推荐阅读
- python - 如何在 jupyter 中使用 RMagic 进行控制台文本输出
- sql - 通过 Proc SQL 语句将列添加到 SAS
- python - 具有多个 Python 依赖项的模板数据流
- asp.net - 命名空间“Microsoft”中不存在类型或命名空间名称“EntityFrameworkCore”
- java - DateTime 转换为 Xa6maSA 格式
- javascript - 如何在 undici 中使用经过身份验证的代理
- reporting-services - SSRS - 执行布尔 IFF 表达式时忽略 NULL
- java - 如何正确转换opencsv中的字段?
- bash - hiera(Puppet)yaml中的cronjob在一行中的几个命令
- python - 允许机器人命令(仅用于测试)