使用 Spring 集成和 Jms 将 Soap 消息放入队列的 Web 服务
Web service putting Soap message in queue with Spring Integration and Jms
我想使用 Spring 集成来公开一个简单的 Web 服务,该服务将传入消息推送到 ActiveMQ 并立即响应。我的首选解决方案是使用 IntegrationFlow 连接到 Jms.outboundAdapter 的 MarshallingWebServiceInboundGateway。在 Gateway 和 IntegrationFlow 片段下方。问题是适配器不提供网关期望的响应 (duh)。我从服务返回的响应是空的 202,延迟大约 1500 毫秒。这是由我在 TRACE 日志中看到的回复超时引起的:
"2020-04-14 17:17:50.101 TRACE 26524 --- [nio-8080-exec-6] o.s.integration.core.MessagingTemplate : Failed to receive message from channel 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@518ffd27' within timeout: 1000"
任何地方都没有硬异常。另一个问题是我无法自己生成响应。在带适配器的 .handle 之后,我无法向 IntegrationFlow 添加任何内容。
- 还有其他方法可以尝试实现该场景吗?
- 如果可能的话,在没有更好方法的情况下,我如何生成和return响应?
很可能正确的方法是在两端都使用网关,但这是不可能的。我等不及响应,直到队列中的消息被消耗和处理。
'''
@Bean
public MarshallingWebServiceInboundGateway greetingWebServiceInboundGateway() {
MarshallingWebServiceInboundGateway inboundGateway = new MarshallingWebServiceInboundGateway(
jaxb2Marshaller()
);
inboundGateway.setRequestChannelName("greetingAsync.input");
inboundGateway.setLoggingEnabled(true);
return inboundGateway;
}
@Bean
public IntegrationFlow greetingAsync() {
return f -> f
.log(LoggingHandler.Level.INFO)
.handle(Jms.outboundAdapter(this.jmsConnectionFactory)
.configureJmsTemplate(c -> {
c.jmsMessageConverter(new MarshallingMessageConverter(jaxb2Marshaller()));
})
.destination(JmsConfig.HELLO_WORLD_QUEUE));
}
'''
逻辑和假设完全正确:你不能在 one-way handle()
之后 return 并且类似于 Jms.outboundAdapter()
.
但是你的问题是你完全错过了 Spring 整合中的 first-class 公民之一 - MessageChannel
。重要的是要理解,即使在像您这样的流程中,端点之间也存在通道(DSL 方法)-隐式(DirectChannel
),就像您的情况一样,或者显式:当您在两者之间使用 channel()
时并可以在那里放置任何可能的实现:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java-dsl-channels
其中一个关键的通道实现是 PublishSubscribeChannel
(JMS 规范中的 topic
),当您可以将相同的消息发送到多个订阅端点时:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/core.html#channel-implementations-publishsubscribechannel
在您的情况下,第一个订阅者应该是您现有的 one-way Jms.outboundAdapter()
。还有一些东西会生成响应并将其回复为 replyChannel
header.
为此 Java DSL 通过 sub-flows 配置提供了一个很好的钩子:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java-dsl-subflows
所以,publish-subscriber 的一些示例可能是这样的:
.publishSubscribeChannel(c -> c
.subscribe(sf -> sf
.handle(Jms.outboundAdapter(this.jmsConnectionFactory))))
.handle([PRODUCE_RESPONSE])
我想使用 Spring 集成来公开一个简单的 Web 服务,该服务将传入消息推送到 ActiveMQ 并立即响应。我的首选解决方案是使用 IntegrationFlow 连接到 Jms.outboundAdapter 的 MarshallingWebServiceInboundGateway。在 Gateway 和 IntegrationFlow 片段下方。问题是适配器不提供网关期望的响应 (duh)。我从服务返回的响应是空的 202,延迟大约 1500 毫秒。这是由我在 TRACE 日志中看到的回复超时引起的:
"2020-04-14 17:17:50.101 TRACE 26524 --- [nio-8080-exec-6] o.s.integration.core.MessagingTemplate : Failed to receive message from channel 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@518ffd27' within timeout: 1000"
任何地方都没有硬异常。另一个问题是我无法自己生成响应。在带适配器的 .handle 之后,我无法向 IntegrationFlow 添加任何内容。
- 还有其他方法可以尝试实现该场景吗?
- 如果可能的话,在没有更好方法的情况下,我如何生成和return响应?
很可能正确的方法是在两端都使用网关,但这是不可能的。我等不及响应,直到队列中的消息被消耗和处理。
'''
@Bean
public MarshallingWebServiceInboundGateway greetingWebServiceInboundGateway() {
MarshallingWebServiceInboundGateway inboundGateway = new MarshallingWebServiceInboundGateway(
jaxb2Marshaller()
);
inboundGateway.setRequestChannelName("greetingAsync.input");
inboundGateway.setLoggingEnabled(true);
return inboundGateway;
}
@Bean
public IntegrationFlow greetingAsync() {
return f -> f
.log(LoggingHandler.Level.INFO)
.handle(Jms.outboundAdapter(this.jmsConnectionFactory)
.configureJmsTemplate(c -> {
c.jmsMessageConverter(new MarshallingMessageConverter(jaxb2Marshaller()));
})
.destination(JmsConfig.HELLO_WORLD_QUEUE));
}
'''
逻辑和假设完全正确:你不能在 one-way handle()
之后 return 并且类似于 Jms.outboundAdapter()
.
但是你的问题是你完全错过了 Spring 整合中的 first-class 公民之一 - MessageChannel
。重要的是要理解,即使在像您这样的流程中,端点之间也存在通道(DSL 方法)-隐式(DirectChannel
),就像您的情况一样,或者显式:当您在两者之间使用 channel()
时并可以在那里放置任何可能的实现:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java-dsl-channels
其中一个关键的通道实现是 PublishSubscribeChannel
(JMS 规范中的 topic
),当您可以将相同的消息发送到多个订阅端点时:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/core.html#channel-implementations-publishsubscribechannel
在您的情况下,第一个订阅者应该是您现有的 one-way Jms.outboundAdapter()
。还有一些东西会生成响应并将其回复为 replyChannel
header.
为此 Java DSL 通过 sub-flows 配置提供了一个很好的钩子:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java-dsl-subflows
所以,publish-subscriber 的一些示例可能是这样的:
.publishSubscribeChannel(c -> c
.subscribe(sf -> sf
.handle(Jms.outboundAdapter(this.jmsConnectionFactory))))
.handle([PRODUCE_RESPONSE])