【问题标题】:Web service putting Soap message in queue with Spring Integration and Jms使用 Spring Integration 和 Jms 将 Soap 消息放入队列的 Web 服务
【发布时间】:2020-07-27 10:16:41
【问题描述】:

我想使用 Spring Integration 公开一个简单的 Web 服务,将传入消息推送到 ActiveMQ 并立即响应。我的首选解决方案是使用 IntegrationFlow 连接到 Jms.outboundAdapter 的 MarshallingWebServiceInboundGateway。在 Gateway 和 IntegrationFlow sn-ps 下方。问题是适配器不提供网关期望的响应(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 添加任何内容。

  1. 我可以通过其他方式尝试实现该场景吗?
  2. 如果可能的话,我如何在没有更好方法的情况下生成并返回响应?

最有可能正确的方法是在两端使用网关,但这是不可能的。在队列中的消息被消费和处理之前,我无法等待响应。

'''

@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));

}

'''

【问题讨论】:

    标签: java spring spring-integration spring-jms


    【解决方案1】:

    逻辑和假设是完全正确的:单向handle()Jms.outboundAdapter() 类似,您无法返回。

    但是您的问题是您完全错过了 Spring Integration 中的一等公民 - 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

    在您的情况下,拳头订阅者应该是您现有的单向 Jms.outboundAdapter()。还有一个东西会产生响应并将其回复到replyChannel 标头中。

    为此,Java DSL 通过子流配置提供了一个不错的钩子:https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java-dsl-subflows

    因此,发布-订阅者的一些示例可能是这样的:

    .publishSubscribeChannel(c -> c
                            .subscribe(sf -> sf
                                      .handle(Jms.outboundAdapter(this.jmsConnectionFactory))))
    .handle([PRODUCE_RESPONSE])
    

    【讨论】:

    • 你是天赐之物!不过,我有一个问题。如果我理解正确,那么在您拆分流程的那一刻,您可能会陷入丑陋的境地,您可能无法将某些东西放入队列中,但会以成功响应。你如何避免这种情况?
    • 这并不总是正确的。请参阅ignoreFailures 选项,默认情况下为false。只要您不向PublishSubscribeChannel 提供任何Executor,第一个订阅者就会阻塞一个线程,直到它完成工作或失败。因此,第二个订阅者在第一个订阅者完成之前不会执行其工作,并且只有在成功时。请参阅我在答案中指出的有关 PublishSubscribeChannel 的文档。
    猜你喜欢
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 2015-02-02
    • 2016-02-10
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多