如何在弹簧集成组件之间传递信息?

时间:2017-03-04 12:21:22

标签: spring-integration spring-integration-sftp

在spring-batch中,可以通过ExecutionContext在各个步骤之间传递数据。您可以一步设置详细信息,然后在下一步中检索。我们在春季整合中有这样的东西吗?

我的用例是我必须从ftp位置获取文件,然后根据某些业务逻辑拆分它,然后处理它们。根据文件名,将派生客户端ID。此客户端ID将用于拆分器,服务激活器和聚合器组件。

从我春天的新手专业水平来看,我找不到任何可以帮助我分享特定运行状态的东西。我想知道spring-integration是否以某种方式提供了这种状态共享上下文。

请告诉我是否有办法在春天的情况下做。

2 个答案:

答案 0 :(得分:1)

通常,您在消息有效负载本身的组件之间传递信息,或者通常通过邮件标头传递信息 - 请参阅Message ConstructionHeader Enricher

答案 1 :(得分:0)

在Spring Integration应用程序中,没有单个ExecutionContext用于状态共享。相反,正如Gary Russel所提到的,每条消息都包含其有效载荷或其标题中的所有信息。

如果您使用Spring Integration Java DSL并希望通过消息头传输clientId,则可以使用enrichHeader转换器。提供HeaderEnricherSpec时,它可以接受一个函数,该函数返回指定标头的动态确定值。截至您的使用案例,这可能如下所示:

return IntegrationFlows
    .from(/*ftp source*/)
    .enrichHeaders(e -> e.headerFunction("clientId", this::deriveClientId))
    ./*split, aggregate, etc the file according to clientId*/

,其中deriveClientId方法可能是一种:

private String deriveClientId(Message<File> fileMessage) {
  String fileName = fileMessage.getHeaders().get(FileHeaders.FILENAME, String.class);
  String clientId = /*some other logic for deriving clientId from*/fileName;
  return clientId;
}

FILENAME标题由FTP消息源提供)

当你需要在下游流程的某个地方访问clientId标题时,你可以像上面提到的文件名一样进行:

String clientId = message.getHeaders().get("clientId", String.class);

但要确保message仍然包含这样的标题,因为它可能在中间流项目中丢失了。如果在某些时候您手动构造消息并进一步发送,则可能会发生这种情况。为了不丢失前面消息中的任何标题,您可以在构建期间复制它们:

  Message<PayloadType> newMessage = MessageBuilder
      .withPayload(payloadValue)
      .copyHeaders(precedingMessage.getHeaders())
      .build();

请注意,消息头在Spring Integration中是不可变的。这意味着您不能只添加或更改现有邮件的标头。您应该创建新消息或使用HeaderEnricher来实现此目的。两种方法的例子如上所述。