Spring Integration 4异步请求/响应

时间:2014-07-16 09:58:47

标签: spring-integration spring-jms spring-dsl

我正在尝试使用Spring Integration v4的DSL API编写一个简单的消息流,如下所示:

       -> in.ch -> Processing -> JmsGatewayOut -> JMS_OUT_QUEUE
Gateway
       <- out.ch <- Processing <- JmsGatewayIn <- JMS_IN_QUEUE

当请求/响应是异步的时,当我通过初始网关注入消息时,消息一直到JMS_OUT_QUEUE。除此消息流之外,还会将回复消息放回JMS_IN_QUEUE,然后由JmsGatewayIn接收。此时,消息被处理并放入out.ch(我知道响应变为out.ch,因为我有一个记录器拦截器,它记录了放置在那里的消息)但是,网关永远不会收到响应。

此消息流之外的系统从JMS_OUT_QUEUE中获取消息并将响应放在JMS_IN_QUEUE中,而不是响应,而是在其自己的JmsOutboundgateway上接收javax.jms.MessageFormatException: MQJMS1061: Unable to deserialize object(我认为它无法反序列化jms)通过查看日志回复对象。)

我显然没有正确配置,但我不确切知道是什么。有谁知道我错过了什么?

使用spring-integration-core-4.0.3.RELEASE,spring-integration-jms-4.0.3.RELEASE,spring-integration-java-dsl-1.0.0.M2,spring-jms-4.0.6 .RELEASE。

我的网关配置如下:

@MessagingGateway
public interface WsGateway {

    @Gateway(requestChannel = "in.ch", replyChannel = "out.ch", 
        replyTimeout = 45000)
    AResponse process(ARequest request);
}

我的集成流程配置如下:

@Configuration
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public class IntegrationConfig {

    @Bean(name = "in.ch")
    public DirectChannel inCh() {
        return new DirectChannel();
    }

    @Bean(name = "out.ch")
    public DirectChannel outCh() {
        return new DirectChannel();
    }   

    @Autowired
    private MQQueueConnectionFactory mqConnectionFactory;

    @Bean
    public IntegrationFlow requestFlow() {

        return IntegrationFlows.from("in.ch")
                .handle("processor", "processARequest")
                .handle(Jms.outboundGateway(mqConnectionFactory)
                        .requestDestination("JMS_OUT_QUEUE")
                        .correlationKey("JMSCorrelationID")
                .get();
    }

    @Bean
    public IntegrationFlow responseFlow() {

        return IntegrationFlows.from(Jms.inboundGateway(mqConnectionFactory)
                .destination("JMS_IN_QUEUE"))
                .handle("processor", "processAResponse")
                .channel("out.ch")
                .get();
    }
}

感谢您对此提供任何帮助, PM。

1 个答案:

答案 0 :(得分:2)

首先,您的配置不好:

  1. 由于你从WsGateway#process开始流程,你真的应该在那里等待回复。 网关的请求/回复功能基于TemporaryReplyChannelheaders作为非序列化值放置。{/ p>

  2. 只要您等待依赖该网关,实际上没有理由提供replyChannel,如果您不打算在回复上做一些发布 - 订阅逻辑。< / p>

  3. 当您向JMS队列发送消息时,您应该了解消费者部分可能是一个separete远程应用程序。最后一个人可能对您的out.ch

  4. 一无所知
  5. JMS请求/回复功能实际上基于JMSCorrelationID,但还不够。这里还有一个ReplyTo JMS头。因此,如果您要发送消费者的回复,您应该完全依赖JmsGatewayIn内容。

  6. 所以我将您的代码更改为:

    @MessagingGateway
    public interface WsGateway {
    
        @Gateway(requestChannel = "in.ch", replyTimeout = 45000)
        AResponse process(ARequest request);
    }
    
    @Configuration
    @EnableIntegration
    @IntegrationComponentScan
    @ComponentScan
    public class IntegrationConfig {
    
        @Bean(name = "in.ch")
        public DirectChannel inCh() {
            return new DirectChannel();
        }
    
        @Autowired
        private MQQueueConnectionFactory mqConnectionFactory;
    
        @Bean
        public IntegrationFlow requestFlow() {
            return IntegrationFlows.from("in.ch")
                    .handle("processor", "processARequest")
                    .handle(Jms.outboundGateway(mqConnectionFactory)
                            .requestDestination("JMS_OUT_QUEUE")
                            .replyDestination("JMS_IN_QUEUE"))
                    .handle("processor", "processAResponse")
                    .get();
        }
    
    }
    

    请告诉我,如果它适合您或尝试探讨为什么您将two-way网关用于一个one-way个案例。也许Jms.outboundAdapter()Jms.inboundAdapter()对你更有利?

    <强>更新

    如何使用Java DSL中的<header-channels-to-string>

    .enrichHeaders(e -> e.headerChannelsToString())