簡體   English   中英

如何使用 Spring 集成流程處理異常

[英]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. 即使它調用了單個激活器服務。
  2. 僅當存在多個封裝單點錯誤的服務激活器/轉換時?

編輯 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

請參閱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