Java Spring集成-可以在特定时间订阅消息

Java Spring集成-可以在特定时间订阅消息,java,spring,spring-integration,enterprise-integration,Java,Spring,Spring Integration,Enterprise Integration,我是Spring集成和EIP的新手 我试图解决自己的问题,但在我的脑海里却找不到合适的解决办法 下面是我需要的流程示例 客户端向SI发送Json数据 HTTP入站网关获得Json数据作为有效负载 此Json数据将用于两个单独的HTTP出站。 但是第二个出站呼叫在第一个出站呼叫的响应之后 将结果回复到步骤0(HTTP入站网关上的replychannel) 我正在考虑使用publishSubscribeChannel或RecipientListRouter向不同的电话发送相同的消息。 但在这种情况下

我是Spring集成和EIP的新手

我试图解决自己的问题,但在我的脑海里却找不到合适的解决办法

下面是我需要的流程示例

  • 客户端向SI发送Json数据
  • HTTP入站网关获得Json数据作为有效负载
  • 此Json数据将用于两个单独的HTTP出站。 但是第二个出站呼叫在第一个出站呼叫的响应之后
  • 将结果回复到步骤0(HTTP入站网关上的replychannel)
  • 我正在考虑使用publishSubscribeChannel或RecipientListRouter向不同的电话发送相同的消息。 但在这种情况下,它需要在特定时间执行第二个http出站。 据我所知,第4步的回复应该是一笔交易

    或者

    是否可以保留消息实例(来自http入站网关的JSON数据),以便在第一次调用之后的第二次调用中使用

    请给我一些想法,如果你有一个样本代码,它一定是美妙的。 目前我正在编写JAVA配置样式,但也欢迎使用XML示例

    更新问题

    我正在尝试添加桥和通道

    这是我的代码,几乎没有什么东西不能像我预期的那样工作

  • 我希望第二个出站处理程序(httpPMGateway)使用来自aIncomingGateway的消息(因此使用publishSubscribeChannel),但在httpJ3Gateway出站处理程序之后,它使用来自httpJ3Gateway的消息。 我使用带有来自httpJ3Gateway的响应消息的路由。 (确定->httpPMgateway,默认->回退通道)

  • 我想从j3ValidationFlow或broadcastFlow的末尾向aIncomingGateway发送响应消息。但aIncomingGateway在发送之前已经收到了回复消息。这是一条日志消息

  • 2017-05-16 11:17:09.061警告11488---[pool-1-thread-1] cMessagingTemplate$TemporaryReplyChannel:已收到回复消息,但 接收线程已收到答复:

    这是代码部分:

    @Bean
    public MessagingGatewaySupport aIncomingGateway() {
        HttpRequestHandlingMessagingGateway handler = new HttpRequestHandlingMessagingGateway(true);
    
        RequestMapping requestMapping = new RequestMapping();
        requestMapping.setMethods(HttpMethod.POST);
        requestMapping.setPathPatterns("/a/incoming");
        requestMapping.setConsumes("application/json");
        requestMapping.setProduces("application/json");
    
    
        handler.setRequestMapping(requestMapping);
        handler.setMessageConverters(getMessageConverters());
        handler.setRequestPayloadType(Amount.class);
    
        handler.setReplyChannelName("backAChannel");
        return handler; 
    }
    
    @Bean
    public MessageHandler httpJ3Gateway(){
        HttpRequestExecutingMessageHandler httpHandler = new HttpRequestExecutingMessageHandler("http://localhost:8080/j3/incoming");
        httpHandler.setHttpMethod(HttpMethod.POST);
        httpHandler.setExpectReply(true);
        httpHandler.setMessageConverters(getMessageConverters());
        httpHandler.setExpectedResponseType(String.class);
        httpHandler.setRequestFactory(requestFactory());
        return httpHandler;
    }
    
    @Bean
    public MessageHandler httpPMGateway(){
        HttpRequestExecutingMessageHandler httpHandler = new HttpRequestExecutingMessageHandler("http://localhost:8080/pm/incoming");
        httpHandler.setHttpMethod(HttpMethod.POST);
        httpHandler.setExpectReply(true);
        httpHandler.setMessageConverters(getMessageConverters());
        httpHandler.setExpectedResponseType(String.class);
        return httpHandler;
    }
    
    @Bean
    public MessageChannel broadChannel(){
        return new ExecutorChannel(Executors.newCachedThreadPool());
    }
    
    @Bean
    @ServiceActivator(inputChannel = "brigdeChannel")
    public MessageHandler bridgeHandler(){
        BridgeHandler handler = new BridgeHandler();
        handler.setOutputChannel(broadChannel());
        return handler;
    }
    
    
    @Bean
    public IntegrationFlow aIncomingFlow() {
        return IntegrationFlows.from(aIncomingGateway())
                .log(LoggingHandler.Level.INFO, "From Inbound http gateway", m -> m.getPayload().toString())
                .publishSubscribeChannel(p -> p
                        .subscribe(s -> s.channel("j3Channel"))
                        .subscribe(s -> s.bridge(b -> bridgeHandler()) )
                        )
                .get();
    }
    
    @Bean
    public IntegrationFlow j3ValidationFlow() {
        return IntegrationFlows.from("j3Channel")
                .log(LoggingHandler.Level.INFO, "Run j3ChannelFlow", m -> m.getPayload().toString())
                .handle(httpJ3Gateway())
                .route("headers.http_statusCode", m -> m
                        .resolutionRequired(false)
                        .channelMapping("OK", "brigdeChannel")
                        .defaultOutputToParentFlow()
                        )
                .channel("backAChannel")
                .get();
    }
    
    @Bean
    public IntegrationFlow broadcastFlow() {
        return IntegrationFlows.from("broadChannel")
                .log(LoggingHandler.Level.INFO, "Run broadcastFlow", m -> m.getPayload().toString())
                .handle(httpPMGateway())
                .channel("backAChannel")
                .get();
    }
    
    请帮我想个主意。

    我提前感谢你。谢谢你在这个愚蠢的问题上帮助我。

    是的;使用发布/订阅频道或收件人列表路由器

    inbound -> ... -> pubsub
    
    pubsub -> outbound1
    
    pubsub -> bridge -> executorChannel -> outbound2
    

    outbound1将在入站线程上运行;outbound2将在另一个线程上运行。

    是;使用发布/订阅频道或收件人列表路由器

    inbound -> ... -> pubsub
    
    pubsub -> outbound1
    
    pubsub -> bridge -> executorChannel -> outbound2
    

    outbound1将在入站线程上运行;outbound2将在另一个线程上运行。

    感谢您的快速回答。我还有一个问题。如果outbound2将运行另一个线程,它可以回复原始的入站(客户端)?是的,如果
    outbound1
    是单向的、不响应的组件(
    Outbound Channel Adapter
    ,就Spring集成而言)。只有一个回复可以发送到等待的入站网关。你好,Gary和Atrem,我更新了我的问题。请帮我想出一个解决这个问题的办法。。。。。提前谢谢你。你不能发送两个回复(正如消息中明确指出的,以及上面@Artem所说的)。您需要将应答从一个网关路由到
    nullChannel
    。或者,如果您需要这两方面的信息,他们需要转到聚合器,您可以在那里合并结果。感谢您的快速回答。我还有一个问题。如果outbound2将运行另一个线程,它可以回复原始的入站(客户端)?是的,如果
    outbound1
    是单向的、不响应的组件(
    Outbound Channel Adapter
    ,就Spring集成而言)。只有一个回复可以发送到等待的入站网关。你好,Gary和Atrem,我更新了我的问题。请帮我想出一个解决这个问题的办法。。。。。提前谢谢你。你不能发送两个回复(正如消息中明确指出的,以及上面@Artem所说的)。您需要将应答从一个网关路由到
    nullChannel
    。或者,如果您需要两者的信息,它们需要转到聚合器,您可以在那里合并结果。