移动到下一个收件人并在收件人列表路由器之一遇到错误时调用错误通道
Move to next recipient and invoke error-channel upon encountering error on one of the recipient-list-router
如果在 "firstChannel" 流程中抛出任何异常,则发生以下两种情况之一:
- 对于 ignore-send-failures="true" 属性,"secondChannel" 是
被调用而 "myErrorChannel" 未被调用。
- 没有 ignore-send-failures="true" 属性,"secondChannel" 不被调用,"myErrorChannel" 被调用。
请建议我如何在 "firstChannel" 流程中抛出任何异常时同时调用 "secondChannel" 和 "myErrorChannel"。
请参阅以下配置详细信息:
<int:channel id="myErrorChannel" datatype="java.lang.Throwable"/>
<int:service-activator input-channel="myErrorChannel" >
<beans:bean class="org.springframework.integration.samples.jms.ErrorServiceActivatorProxy"></beans:bean>
</int:service-activator>
<jms:message-driven-channel-adapter id="jmsIn" channel="jmsInChannel" destination="requestQueue" error-channel="myErrorChannel"/>
<int:channel id="firstChannel" />
<int:channel id="secondChannel" />
<int:recipient-list-router id="recipientListRouter" input-channel="jmsInChannel" ignore-send-failures="true">
<int:recipient channel="firstChannel"/>
<int:recipient channel="secondChannel"/>
</int:recipient-list-router>
<int:channel id="firstChannelOutboundChannel"/>
<int:transformer input-channel="firstChannel" output-channel="firstChannelOutboundChannel">
<beans:bean class="org.springframework.integration.samples.jms.FileIOTransformer"></beans:bean>
</int:transformer>
<jms:outbound-channel-adapter
id="firstChannelOutbound"
channel="firstChannelOutboundChannel"
connection-factory="jmsConnectionFactory"
destination="outputQueueOne"
auto-startup="true" />
<jms:outbound-channel-adapter
id="secondChannelOutbound"
channel="secondChannel"
connection-factory="jmsConnectionFactory"
destination="outputQueueTwo"
auto-startup="true"/>
它以这种方式工作,因为下游流就像流中第一个组件的单个黑盒调用。我们从那里发送一条消息,因此我们只能在那里捕获一个异常并停止执行。
然而,我们可以将 try-catch 机制移近有罪代码。由于第一个收件人有问题,因此您必须在那里处理错误并吞下异常。这样收件人列表路由器就不会知道第一个收件人的错误并会调用第二个。
在 FileIOTransformer
中添加 try-catch 的最简单方法。但是,您可以使用 ExpressionEvaluatingRequestHandlerAdvice
并将其 trapException
设置为 true:https://docs.spring.io/spring-integration/docs/4.3.12.RELEASE/reference/html/messaging-endpoints-chapter.html#expression-advice。但是需要记住,这种建议只直接应用于当前组件。它不会在下游捕获异常。
另一个技巧是使用 try-catch 实现 ChannelInterceptor
并将其添加到 firstChannel
.
如果在 "firstChannel" 流程中抛出任何异常,则发生以下两种情况之一:
- 对于 ignore-send-failures="true" 属性,"secondChannel" 是 被调用而 "myErrorChannel" 未被调用。
- 没有 ignore-send-failures="true" 属性,"secondChannel" 不被调用,"myErrorChannel" 被调用。
请建议我如何在 "firstChannel" 流程中抛出任何异常时同时调用 "secondChannel" 和 "myErrorChannel"。 请参阅以下配置详细信息:
<int:channel id="myErrorChannel" datatype="java.lang.Throwable"/>
<int:service-activator input-channel="myErrorChannel" >
<beans:bean class="org.springframework.integration.samples.jms.ErrorServiceActivatorProxy"></beans:bean>
</int:service-activator>
<jms:message-driven-channel-adapter id="jmsIn" channel="jmsInChannel" destination="requestQueue" error-channel="myErrorChannel"/>
<int:channel id="firstChannel" />
<int:channel id="secondChannel" />
<int:recipient-list-router id="recipientListRouter" input-channel="jmsInChannel" ignore-send-failures="true">
<int:recipient channel="firstChannel"/>
<int:recipient channel="secondChannel"/>
</int:recipient-list-router>
<int:channel id="firstChannelOutboundChannel"/>
<int:transformer input-channel="firstChannel" output-channel="firstChannelOutboundChannel">
<beans:bean class="org.springframework.integration.samples.jms.FileIOTransformer"></beans:bean>
</int:transformer>
<jms:outbound-channel-adapter
id="firstChannelOutbound"
channel="firstChannelOutboundChannel"
connection-factory="jmsConnectionFactory"
destination="outputQueueOne"
auto-startup="true" />
<jms:outbound-channel-adapter
id="secondChannelOutbound"
channel="secondChannel"
connection-factory="jmsConnectionFactory"
destination="outputQueueTwo"
auto-startup="true"/>
它以这种方式工作,因为下游流就像流中第一个组件的单个黑盒调用。我们从那里发送一条消息,因此我们只能在那里捕获一个异常并停止执行。
然而,我们可以将 try-catch 机制移近有罪代码。由于第一个收件人有问题,因此您必须在那里处理错误并吞下异常。这样收件人列表路由器就不会知道第一个收件人的错误并会调用第二个。
在 FileIOTransformer
中添加 try-catch 的最简单方法。但是,您可以使用 ExpressionEvaluatingRequestHandlerAdvice
并将其 trapException
设置为 true:https://docs.spring.io/spring-integration/docs/4.3.12.RELEASE/reference/html/messaging-endpoints-chapter.html#expression-advice。但是需要记住,这种建议只直接应用于当前组件。它不会在下游捕获异常。
另一个技巧是使用 try-catch 实现 ChannelInterceptor
并将其添加到 firstChannel
.