我在弹簧集成方面有以下设置。
<int-http:inbound-gateway id="restListener"
request-channel="restChannel"
reply-channel="restResponseChannel"
path="/service"
supported-methods="POST"
reply-timeout="5000"
</int-http:inbound-gateway>
<int:channel id="restChannel"/>
<int:channel id="restResponseChannel"/>
<int:service-activator input-channel="restChannel"
ref="restRequestHandler"
method="handleRestRequest"/>
我在网关上收到2种不同类型的POST请求,并将它们都传递给service-activator
进行处理。在一种类型的POST请求中,service-activator
可以立即处理它并使用标准响应进行回复。但是,其他类型的请求将通过不同的通道路由并由不同的处理器处理(取决于内容)。我希望输出处理两种类型的请求作为REST调用的response
发送。
对于第一类请求,我可以简单地执行此操作
public void handleRestRequest(Message<JsonNode> postMessage) {
if (type1) {
// Do processing
restResponseChannel.send(MessageBuilder
.withPayload("{\"result\":\"success!\"}")
.copyHeaders(postMessage.getHeaders())
.build());
} else {
// send to another channel for further processing
}
}
但是对于第二种类型的请求,如果我尝试send
我的输出到restResponseChannel
(没有标题),那么我会得到以下异常
org.springframework.messaging.core.DestinationResolutionException:没有 输出通道或replyChannel标头可用
我无法访问第二类请求的原始标头。如何将输出发送到reply-channel
? (我在某处看到网关创建了一个匿名通道来连接reply-channel
并且没有这些标头导致异常,但是我自己并不完全理解调试这个的基本机制。
答案 0 :(得分:2)
你完全理解这一点。
如果您没有携带请求标头,则没有TemporaryReplyChannel
标头可以将回复与响应相关联。请参阅GenericMessagingTemplate.doSendAndReceive()
了解实施情况:
TemporaryReplyChannel tempReplyChannel = new TemporaryReplyChannel(this.throwExceptionOnLateReply);
requestMessage = MessageBuilder.fromMessage(requestMessage).setReplyChannel(tempReplyChannel)
.setHeader(this.sendTimeoutHeader, null)
.setHeader(this.receiveTimeoutHeader, null)
.setErrorChannel(tempReplyChannel).build();
try {
doSend(channel, requestMessage, sendTimeout);
}
catch (RuntimeException ex) {
tempReplyChannel.setSendFailed(true);
throw ex;
}
Message<?> replyMessage = this.doReceive(tempReplyChannel, receiveTimeout);
所以,如果没有那个标题,就没有可能接受回复。行为与许多其他消息传递replyAddress
模式中的行为相同。
reply-channel="restResponseChannel"
只是为了方便您不想查询下一个频道的标题,或者您希望不仅向响应发送回复而是向其他地方发送回复 - 发布 - 订阅图案。
除非随身携带标题,否则您无法选择。一种情况是直接使用Message
,另一种情况是使用@Headers Map<String, Object>
服务方法。