一个聚合器,可以在处理所有记录时释放,即使有错误也是如此

时间:2014-01-15 10:28:05

标签: spring-integration

我正在使用Spring Integration构建一个system,它将文件中的所有行作为记录处理。由于某些字符串记录格式错误,我通过SplitterAggregator组合在应用程序中有多条路径(我正在构建Aggregator)。

此外,有些记录是如此格式错误,以至于它们实际上是错误的。但是我要求必须处理所有记录,因此我必须单独识别并记录严重的畸形错误并完成处理文件。换句话说,我不能无法处理文件,而只能记录错误。


聚合
我打算通过修改传入消息上的标题并将消息传递到可以搜索这种参数存在的Aggregator来实现处理严重错误记录的目标。我将在处理器和聚合器的某些错误处理情况下有效地进行手动编码。

Aggregator的发布策略将在处理完所有邮件时生效。


代码提取
此代码来自Matt Vickery的blog entry。他构造了一条全新的消息(使用MessageBuilder并传输标题),而我只是在Message标题中添加了一些内容。他将此代码包含在网关中,随后将Message转移到Aggregator

public Message<AvsResponse> service(Message<AvsRequest> message) {

    Assert.notNull(message, MISSING_MANDATORY_ARG);
    Assert.notNull(message.getPayload(), MISSING_MANDATORY_ARG);

    MessageHeaders requestMessageHeaders = message.getHeaders();
    Message<AvsResponse> responseMessage = null;
    try {
        logger.debug("Entering AVS Gateway");
        responseMessage = avsGateway.send(message);
        if (responseMessage == null)
            responseMessage = buildNewResponse(requestMessageHeaders,
                    AvsResponseType.NULL_RESULT);
        logger.debug("Exited AVS Gateway");

        return responseMessage;
    } 
    catch (Exception e) {
        return buildNewResponse(responseMessage, requestMessageHeaders,
                AvsResponseType.EXCEPTION_RESULT, e);
    }
}


混乱(至少,我所知道的)
我的问题如下:

  • 当我有这样的发布策略(处理完所有消息)时,这是确保所有消息都通过Aggregator的最佳方法吗?
  • 当使用Aggregator时,在实际情况下似乎需要访问前一步中的Message,而不是仅传递和处理简单的POJO。这是真的还是我应该做些什么来简化我的设计,以便我可以避免Message

我遇到了Matt Vickery的blog entry,展示了他如何实现与聚合器类似的东西。我正在以他的工作为指导。

P.S。根据Artem Bilan的advice,我正在避免创建自己的消息并让SI将它们转换为Messages

1 个答案:

答案 0 :(得分:3)

如果payload有效,则聚合器没有区别。其一般目的是为一个Message构建一个List(默认情况下)有效负载。它通过sequenceDetails中的MessageHeaders来实现。这是第一次。

如果您使用Splitter,则有责任使用默认sequenceDetails来丰富每个生成的消息。所以,如果你有这个配置:

<splitter/>

<aggregator/>

如果您的入站有效负载为List,那么您在聚合器之后也会得到List

我假设您的Splitter只从文件行生成String有效负载。

然后将每条消息传递给某个服务/转换器。

您可以将结果传递给聚合器。

但正如您所说,有些有效负载无效且您的processor因异常而失败。

那么,那个POJO方法中只有try...catch怎么样,并返回带有错误指示符的一些有效负载,例如:简单的字符串“哎呀!”。

如前所述:POJO方法的结果将被推送到Message by Framework的payload。什么是魔术,sequenceDetails也会出现MessageHeaders

我没有理由为此任务编写一些自定义ReleaseStrategy,甚至没有任何其他聚合器的策略......

让我知道,你不明白。

<强>更新

要向消息头添加一些error-indicator并且不抛出异常,从代码构建新消息真的会更简单,而不是通过某些error-channel流:

try {
   return [GOOD_RESULT];
}
catch(Exception e) {
   return MessageBuilder.withPayload(payload).setHeader("ERROR", e.getMessage()).build();
}

但在这种情况下,您应该使用<service-activator>而不是<transformer>,因为最后一个不会从入站消息中复制标头。你确实需要它们 - setHeader用于聚合器。