[英]How to handle Exceptions with a Spring Integration Flow
我正在嘗試使用 spring 集成來執行以下操作。
我想從輸入通道讀取傳入消息,該消息會引發一系列步驟並生成最終消息。每個步驟都可以引發異常。 這可能是由於 DB 調用或 ExternalCall 等。每個步驟都被視為服務激活器。 如果一切順利,則生成最終消息。我需要將每個步驟拋出的每個異常作為單獨的情況處理,然后生成適當的最終消息。
使用下面的 xml,我編寫了一個測試代碼,該代碼在成功時通過,但是當發生錯誤時,雖然我看到在 postSend (sent=true) 通道 'bean'finalChannel' 日志中生成的最終消息,但該過程不會返回到最后的隊列。
為什么會發生這種情況?
<?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我添加了一個請求處理程序建議鏈引用一個 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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.