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

时间:2017-05-15 18:11:26

标签: java spring spring-integration enterprise-integration

我是Spring Integration和EIP的新手。

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

以下是我需要的流程示例。

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

    或者...

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

    请给我一些想法,如果你有一个示例代码,那一定很棒。 目前我正在编写JAVA配置样式,但XML样本也欢迎。

    更新问题

    我正在尝试添加bridge和executorChannel。

    这是我的代码,很少有东西没有像我预期的那样工作。

    1. 我想第二个出站处理程序(httpPMGateway)使用来自aIncomingGateway的消息(因为这个使用publishSubscribeChannel),但是在httpJ3Gateway出站处理程序之后,它使用来自httpJ3Gateway的消息。 我使用来自httpJ3Gateway的响应消息的路由。 (好的 - > httpPMgateway,默认 - > backAChannel)

    2. 我想从j3ValidationFlow或broadcastFlow的末尾向acomingGateway发送响应消息。但是,在他们发送之前,aIncomingGateway已收到回复消息。这是日志消息。

    3.   

      2017-05-16 11:17:09.061 WARN 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();
      }
      

      请帮我理解。
      我提前感激。感谢您帮助我解决这个愚蠢的问题。

1 个答案:

答案 0 :(得分:0)

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

inbound -> ... -> pubsub

pubsub -> outbound1

pubsub -> bridge -> executorChannel -> outbound2

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