簡體   English   中英

如何從Spring Integration中的方法返回值而不中斷原始Message流?

[英]How do I return a value from a method in Spring Integration and not interrupt the original Message flow?

fileProcessor bean的encode方法負責編碼視頻文件。 如果遇到問題,則不應刪除該文件,否則如果一切正常,則可以刪除。 現在,在不更改有效負載的情況下保留Message流的唯一方法是使encode方法返回void 我需要返回一些“標題”信息,以便SI以后可以刪除該文件。 我嘗試使用MessageBuilder創建一個Message<File>並返回它,但是當它到達下一個通道時它已被包裝並且Message有一條Message ,因此我的表達式無法觸發刪除。

我想我可以使用一個包裝的Message並在對象圖中挖掘一個級別,但這看起來很笨拙。

在不破壞原始Message有效負載且不使用SI通道和發送方式污染我的POJO編碼方法的情況下,獲取某些返回值的最佳方法是什么?

這是我的配置:

<!-- ########################## -->
<!-- ###      Encoding      ### -->
<!-- ########################## -->

<file:inbound-channel-adapter 
    directory="${paths.encode}"
    channel="encodeChannel"
    filename-regex="${encode.regex}"
    prevent-duplicates="false">
    <int:poller fixed-rate="5000"/>
</file:inbound-channel-adapter>

<int:service-activator
    input-channel="encodeChannel"
    output-channel="encodeResultChannel"
    ref="fileProcessor"
    method="encode">
</int:service-activator>    

<!-- This is where I'm having trouble.  -->
<!-- I don't expect this router to work. -->
<int:router
    input-channel="encodeResultChannel"
    expression="payload">       
    <int:mapping value="true" channel="encodeDeleteChannel"/>
    <int:mapping value="false" channel="stdout"/>
</int:router>

<int:service-activator
    input-channel="encodeDeleteChannel"
    expression="payload.delete()"
    output-channel="stdout">
</int:service-activator>

<stream:stdout-channel-adapter 
    id="stdout" 
    append-newline="true" />

編輯:

我正在使用:

<properties>
    <spring-framework.version>3.2.3.RELEASE</spring-framework.version>
</properties>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring-framework.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-integration</artifactId>
    <version>1.1.0.BUILD-SNAPSHOT</version>
</dependency>

EDIT2:

這是更新的配置

<!-- ########################## -->
<!-- ###      Encoding      ### -->
<!-- ########################## -->

<file:inbound-channel-adapter 
    directory="${paths.encode}"
    channel="filePickupChannel"
    filename-regex="${encode.regex}"
    prevent-duplicates="false">
    <int:poller fixed-rate="5000"/>
</file:inbound-channel-adapter>

<int:header-enricher
    input-channel="filePickupChannel"
    output-channel="encodeChannel">
    <int:header name="origFile" expression="payload"/>
</int:header-enricher>

<int:service-activator
    input-channel="encodeChannel"
    output-channel="encodeResultChannel"
    ref="fileProcessor"
    method="encode">
</int:service-activator>    

<int:router
    input-channel="encodeResultChannel"
    ignore-send-failures="false"
    default-output-channel="stdout"
    expression="payload">       
    <int:mapping value="true" channel="encodeDeleteChannel"/>
    <int:mapping value="false" channel="stdout"/>
</int:router>

<int:service-activator
    input-channel="encodeDeleteChannel"
    expression="headers['origFile'].delete()"
    output-channel="stdout">
</int:service-activator>

您使用的是什么版本的Spring Integration和Spring Framework?

fileProcessor.encode()的簽名是什么樣的?

你不應該得到一個嵌套的Message<?>AbstractReplyProducingMessageHandler有以下邏輯......

private Message<?> createReplyMessage(Object reply, MessageHeaders requestHeaders) {
    AbstractIntegrationMessageBuilder<?> builder = null;
    if (reply instanceof Message<?>) {
        if (!this.shouldCopyRequestHeaders()) {
            return (Message<?>) reply;
        }
        builder = this.getMessageBuilderFactory().fromMessage((Message<?>) reply);
    }

...

    if (this.shouldCopyRequestHeaders()) {
        builder.copyHeadersIfAbsent(requestHeaders);
    }
    return builder.build();
}

因此,如果您返回Message<?> ,則會返回您的消息(使用您未設置的任何入站標頭進行增強)。

您是否在Spring Framework 4.0.x中使用Spring Integration 3.0.x? 如果是這樣,您需要小心返回org.springframework.integration消息,而不是org.springframework.messaging消息。

如果你返回一個org.springframework.messaging消息,Spring Integration確實會將它包裝在Spring Integration Message中。

核心消息傳遞類被移動到Spring Framework 4.0中的spring-messaging模塊,因此它們可以用於websockets,STOMP等。

Spring Integration 4.0.x現在也使用這些類,因此你不會在類路徑上看到它們; 避免混淆。 在Spring Framework 3.0.x中使用Spring Integration 3.0.x時,您需要非常謹慎地使用正確的類。

但是,一般情況下,我們不建議在您的代碼中添加框架類(例如Message<?> ),而是使用POJO,框架將處理消息傳遞細節......

boolean encode(File file) {...}

如果您需要在編碼后訪問有效負載,請考慮事先將其提升為標頭。

<int:header-enricher ...>
    <int:header name="origFile" expression="payload" />
</int:header-enricher>

然后在編碼后使用expression="headers['origFile'].delete()

編輯:

或者,在成功時返回文件(因此它成為新的有效負載),並在失敗時返回null或拋出異常,並且不會執行下游流。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM