简体   繁体   English

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

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

The encode method of the fileProcessor bean is responsible for encoding a video file. fileProcessor bean的encode方法负责编码视频文件。 If it encounters a problem the file should not be deleted, otherwise if everything is well, it is okay to delete. 如果遇到问题,则不应删除该文件,否则如果一切正常,则可以删除。 Right now, the only way to preserve the Message flow without changing the payload is to make the encode method return void . 现在,在不更改有效负载的情况下保留Message流的唯一方法是使encode方法返回void I need to return some 'header' information though so that SI can later delete the file. 我需要返回一些“标题”信息,以便SI以后可以删除该文件。 I tried using MessageBuilder to create a Message<File> and return that, but when it arrives in the next channel it has been wrapped and there is a Message inside a Message , therefore my expression doesn't work to trigger the delete. 我尝试使用MessageBuilder创建一个Message<File>并返回它,但是当它到达下一个通道时它已被包装并且Message有一条Message ,因此我的表达式无法触发删除。

I suppose I could use a wrapped Message and dig down one level in the object graph, but that seems clunky. 我想我可以使用一个包装的Message并在对象图中挖掘一个级别,但这看起来很笨拙。

What is the best approach to tacking on some return value without destroying the original Message payload and without polluting my POJO encode method with SI channels and sending? 在不破坏原始Message有效负载且不使用SI通道和发送方式污染我的POJO编码方法的情况下,获取某些返回值的最佳方法是什么?

Here is my configuration: 这是我的配置:

<!-- ########################## -->
<!-- ###      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" />

edit: 编辑:

I'm using: 我正在使用:

<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: EDIT2:

here's the updated configuration 这是更新的配置

<!-- ########################## -->
<!-- ###      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>

What version of Spring Integration and Spring Framework are you using? 您使用的是什么版本的Spring Integration和Spring Framework?

What does the signature of fileProcessor.encode() look like? fileProcessor.encode()的签名是什么样的?

You should not get a nested Message<?> , the AbstractReplyProducingMessageHandler has the following logic... 你不应该得到一个嵌套的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();
}

So, if you return a Message<?> your message is returned (enhanced with any inbound headers that you didn't set). 因此,如果您返回Message<?> ,则会返回您的消息(使用您未设置的任何入站标头进行增强)。

Are you using Spring Integration 3.0.x with Spring Framework 4.0.x? 您是否在Spring Framework 4.0.x中使用Spring Integration 3.0.x? If so, you need to be careful to return an org.springframework.integration Message, not an org.springframework.messaging message. 如果是这样,您需要小心返回org.springframework.integration消息,而不是org.springframework.messaging消息。

If you return an org.springframework.messaging Message, Spring Integration will indeed wrap it in a Spring Integration Message. 如果你返回一个org.springframework.messaging消息,Spring Integration确实会将它包装在Spring Integration Message中。

Core messaging classes were moved to the spring-messaging module in Spring Framework 4.0, so they can be used for websockets, STOMP etc. 核心消息传递类被移动到Spring Framework 4.0中的spring-messaging模块,因此它们可以用于websockets,STOMP等。

Spring Integration 4.0.x now uses those classes as well so you won't see both on the classpath; Spring Integration 4.0.x现在也使用这些类,因此你不会在类路径上看到它们; avoiding the confusion. 避免混淆。 When using Spring Integration 3.0.x with Spring Framework 4.0.x, you need to take great care to use the right classes. 在Spring Framework 3.0.x中使用Spring Integration 3.0.x时,您需要非常谨慎地使用正确的类。

In general, however, we don't recommend adding framework classes (such as Message<?> ) to your code, use POJOs instead, and the framework will take care of the messaging details... 但是,一般情况下,我们不建议在您的代码中添加框架类(例如Message<?> ),而是使用POJO,框架将处理消息传递细节......

boolean encode(File file) {...}

If you need to access the payload after the encode, consider promoting it to a header beforehand. 如果您需要在编码后访问有效负载,请考虑事先将其提升为标头。

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

Then use expression="headers['origFile'].delete() after the encode. 然后在编码后使用expression="headers['origFile'].delete()

EDIT: 编辑:

Or, return the file (so it becomes the new payload) on success and, on failure, return null or throw an exception and the downstream flow won't be executed. 或者,在成功时返回文件(因此它成为新的有效负载),并在失败时返回null或抛出异常,并且不会执行下游流。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 object 从 spring 集成中的流传递到下一个流? - How do I pass an object to the next flow from a flow in spring integration? 如何中断或取消Spring Integration Java DSL流? - How to Interrupt or Cancel a Spring Integration Java DSL flow? 如何使用Spring Integration将bean的返回值传递给XML属性? 最有可能涉及SpEL - How do I pass the return value of a bean to an XML attribute using Spring Integration? Most likely involves SpEL 如何从Spring Integration中的消息有效内容中获取Object值 - How to get Object value from message payload in Spring Integration 如何中断Spring Web流并清理资源 - How to interrupt a Spring Web flow and Cleanup the resources 消息标头是 Spring 带有子流的集成流 - Message Headers is Spring Integration flow with subflows 如何返回Java原始列表中缺少的值? - How can I return a value that is missing from an original list in java? 如何在另一个不同于调用方法的方法中使用一个方法的返回值? - How do I use the return value from a method in another method different from the calling method? 为什么带有 void return 的 Gateway 正在制作异步流,但它在返回值时会同步? Spring 集成 - Why does Gateway with void return is making async flow but it does sync when it return value? Spring Integration 如何在要返回的方法中从lambda返回值? - How do I return a value from a lambda within the method I want to return on?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM