拦截Spring集成http:inbound-gateway的replyChannel

时间:2015-09-16 12:08:47

标签: java spring spring-integration

我想在reply-channel的{​​{1}}上应用拦截器,以将某些与事件相关的数据保存到表中。流程在http:inbound-gateway继续,然后转到chain。举个例子,让我们在此流程结束时选择header-value-router,其中未指定service-activator。在这种情况下,replyChannel标头包含output-channel对象(匿名回复频道)而不是网关TemporaryReplyChannel。这样就永远不会调用拦截器。

有没有办法强迫"强迫"使用指定的回复频道? The Spring document表示

  

通过定义默认回复频道,您可以指向您选择的频道,在这种情况下,该频道将是发布 - 订阅频道。网关将从它创建一个桥接到存储在标题中的临时匿名回复通道。

我尝试使用reply-channel作为publish-subscribe-channel,但它没有任何区别。也许我误解了这篇文章......

在我的链条中,我还尝试了reply-channel。我想用我想拦截的频道的id覆盖replyChannel的值(submit.reply.channel)。调试时,我能够看到" submit.reply.channel"在标题中,但后来我得到一个异常header-enricher并停止尝试; - )

代码段

java.lang.NoClassDefFoundError: org/springframework/transaction/interceptor/NoRollbackRuleAttribute

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

唯一“简单”的方法是通过最后一个端点上的output-channel显式发送回复。

事实上,当你发送到声明的频道时发生的一切都是回复频道只是桥接到replyChannel标题。

您可以通过在另一个标头中保存replyChannel标头,将replyChannel标头设置为其他某个频道(您可以拦截);然后在将回复返回到网关之前将replyChannel标头恢复到已保存的通道。

编辑:

示例配置...

<int:channel id="in" />

<int:header-enricher input-channel="in" output-channel="next">
    <int:header name="origReplyChannel" expression="headers['replyChannel']"/>
    <int:reply-channel ref="myReplies" overwrite="true" />
</int:header-enricher>

<int:router input-channel="next" expression="payload.equals('foo')">
    <int:mapping value="true" channel="channel1" />
    <int:mapping value="false" channel="channel2" />
</int:router>

<int:transformer input-channel="channel1" expression="payload.toUpperCase()" />

<int:transformer input-channel="channel2" expression="payload + payload" />

<int:channel id="myReplies" />

<!-- restore the reply channel -->
<int:header-enricher input-channel="myReplies" output-channel="tapped">
    <int:reply-channel expression="headers['origReplyChannel']" overwrite="true" />
</int:header-enricher>

<int:channel id="tapped">
    <int:interceptors>
        <int:wire-tap channel="loggingChannel" />
    </int:interceptors>
</int:channel>

<int:logging-channel-adapter id="loggingChannel" log-full-message="true" logger-name="tapInbound"
    level="INFO" />

<!-- route reply -->
<int:bridge id="bridgeToNowhere" input-channel="tapped" />

测试:

MessageChannel channel = context.getBean("in", MessageChannel.class);
MessagingTemplate template = new MessagingTemplate(channel);
String reply = template.convertSendAndReceive("foo", String.class);
System.out.println(reply);
reply = template.convertSendAndReceive("bar", String.class);
System.out.println(reply);  }

结果:

09:36:30.224 INFO  [main][tapInbound] GenericMessage [payload=FOO, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@fba92d3, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@fba92d3, id=326a610f-80c6-5b74-0158-e3644b732aab, origReplyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@fba92d3, timestamp=1442496990223}]
FOO
09:36:30.227 INFO  [main][tapInbound] GenericMessage [payload=barbar, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@662b4c69, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@662b4c69, id=d161917c-ca73-a5a9-d0f1-d7a4346a459e, origReplyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@662b4c69, timestamp=1442496990227}]
barbar