我在这里有一个简单的“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
答案 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());
每个请求都需要自己的回复通道标头,因此我们知道如何将回复路由到正确的请求线程。