我正在使用Spring Integration构建一个system,它将文件中的所有行作为记录处理。由于某些字符串记录格式错误,我通过Splitter
和Aggregator
组合在应用程序中有多条路径(我正在构建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
答案 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
用于聚合器。