Spring Integration inbound-gateway reply-channel没有通道订阅者

时间:2016-02-26 06:50:32

标签: java spring spring-integration

我在这里有一个简单的“Hello World”示例工作流,我希望公开一个以纯文本形式响应的inbound-gateway Web服务。我相信我将回复路由到myReplyChannel的方式不正确。

<int:channel id="myRequestChannel"/>
<int:channel id="myReplyChannel"/>

<int-http:inbound-gateway id="myGateway"
                          path="/hi"
                          supported-methods="GET"
                          request-channel="myRequestChannel"
                          reply-channel="myReplyChannel"/>

<int:transformer input-channel="myRequestChannel"
                 output-channel="myReplyChannel"
                 expression="'Hello World!'"/>

这在部署时有效,但是当我第一次调用该服务时,我看到了这个记录:

Adding {bridge:null} as a subscriber to the 'myReplyChannel' channel
Channel 'org.springframework.web.context.WebApplicationContext:myReplyChannel' has 1 subscriber(s).
started org.springframework.integration.endpoint.EventDrivenConsumer@4eef7503

看起来Spring在最后一刻添加了myReplyChannel的订阅者。我宁愿自己做得正确。

单元测试

我写了一个简单的单元测试来调试这个..

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:hello.xml" })
public class HelloWorldTest {

    @Autowired
    private MessageChannel myRequestChannel;

    @Test
    public void test() {
        myRequestChannel.send(MessageBuilder.withPayload("").build());
    }

}

这出错了:

org.springframework.messaging.MessageDeliveryException:
  Dispatcher has no subscribers for channel
'org.springframework.context.support.GenericApplicationContext@64485a47.myReplyChannel'.

这对我来说就像我的配置错了,这里Spring并不牵着我的手。

备用配置:

我尝试将myReplyChannel全部放在一起,并且日志中没有任何内容。

<int:channel id="myRequestChannel"/>

<int-http:inbound-gateway id="myGateway"
                          path="/ok"
                          supported-methods="GET"
                          request-channel="myRequestChannel"/>

<int:transformer input-channel="myRequestChannel" expression="'OK'"/>

这是正确的设置吗?如果是,那么reply-channel参数是什么?

使用此配置,我的单元测试中出现以下错误:

org.springframework.messaging.MessagingException:
  org.springframework.messaging.core.DestinationResolutionException:
    no output-channel or replyChannel header available

1 个答案:

答案 0 :(得分:0)

  

将{bridge:null}添加为'myReplyChannel'频道的订阅者

  

调试此

没有什么可以“调试”。这只是来自框架内部的DEBUG消息。每个请求都会获得一个专用的replyChannel标头。通常,您不需要网关上的reply-channel;当框架到达某个没有output-channel的组件时(正如您在第二次测试中找到的那样),框架将自动路由到此请求的回复通道标头。

如果您执行指定回复频道,网关会在内部创建一个网桥,以便在那里专门发送的任何回复都会桥接到请求的replyChannel标头。

通常情况下,指定回复频道的唯一原因是,如果您想对回复执行其他操作(例如,请点击频道以记录回复,或将频道设为发布 - 订阅频道,以便您可以发送其他地方的答复副本。)

您的测试失败,因为您没有像网关一样填充replyChannel标头。

如果要在测试代码中模拟HTTP网关,请使用消息传递网关,或者只使用MessagingTemplate.convertSendAndReceive() - 任何一个都会在请求消息中正确设置replyChannel标头。

或者,使用:

    myRequestChannel.send(MessageBuilder.withPayload("")
                             .setReplyChannel(new QueueChannel())
                             .build());

每个请求都需要自己的回复通道标头,因此我们知道如何将回复路由到正确的请求线程。