使用骆驼拆分器拆分列表列表

Split a List of Lists with camel splitter

我创建了许多 ArrayLists 来保存要拆分为它们自己的实体的单独实体的集合。这些被添加到一个 ArrayList,然后被推送到我尝试拆分列表列表的交换。我似乎无法拆分列表列表。

尝试了 Splitter 的多种变体,使用令牌等。

List<String> serviceRecords = new ArrayList<String>();  //holds an assets collection
List<String> toRecords = new ArrayList<String>();       //holds all asset collections

收集属于一个组的项目后,将它们添加到 ArrayList。

serviceRecords.add(sb.toString());

添加完所有项目后,列表将添加到列表中。

toRecords.addAll(serviceRecords);

然后我将列表推送到交易所

exchange.getIn().setBody(toRecords);

然后是 XML 路线,它在尝试不同的东西时处于混乱状态。 none 其中工作。必须有一个拆分列表列表的技巧。

    <route autoStartup="true" id="core.fleet.asset.splitterRoute">
        <from id="_from4" uri="{{fileEnrichmentEndpoint}}"/>
        <process id="_process4" ref="assetCollectorProcessor"/>
        <process id="_process5" ref="fleetAssetSplitter"/>
        <split id="FleetSplit">    <!-- strategyRef="tsAggregationStrategy" -->
        <!-- <simple>${body}</simple> -->
        <tokenize token="BLOCKMarker"/>
          <log id="splitBody" message="Split Body: ${body}"/>
          <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMddhhmmss}.csv"/>
          <!-- <process id="getName" ref="fleetAssetFileName"/> -->
          <!-- <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMdd}.csv"/> -->
        </split>
        <!-- <to id="_splitOut" uri="{{fileSplitDestination}}/?fileName=GCMS_asset_${date:now:yyyyMMdd}.csv"/> -->
        <stop/>
    </route>

List of Lists 拆分生成的多个文件。

您可以根据需要使用JavaBean来实现嵌套的Splitter逻辑。

如果标准Splitter EIP做不到你想要的,你可以用一个bean告诉他如何拆分你消息的payload。

因此,如果您将 Splitter 配置为使用您的自定义 bean

from("direct:split")
    .log("Original body: ${body}")
    .split().method(new SplitterBean(), "splitServiceRecords")
    .log("Message part: ${body}")
    .to("mock:end");

并且该 bean 只需在结果列表中收集所有服务记录(来自您的示例)

public List<String> splitServiceRecords(List<List<String>> body) {
    List<String> collectedServiceRecords = new ArrayList<String>();
    // iterate over List containing lists and add each item of
    // the inner list to the Splitter result
    for (List<String> serviceRecords : body) {
        for (String serviceRecord : serviceRecords) {
            collectedServiceRecords.add(serviceRecord);
        }
    }
    return collectedServiceRecords;
}

列表的列表将成为包含所有项目的单个列表,每个项目成为由 Camel 进一步路由的消息。

以上路线的日志输出:

INFO: Original body: [[Foo, Bar, Baz], [Record, item, thing]]
...
INFO: Message part: Foo
INFO: Message part: Bar
INFO: Message part: Baz
INFO: Message part: Record
INFO: Message part: item
INFO: Message part: thing

我不知道删除这个还是为了其他人的利益而离开。
在发现我使用了错误的 List 方法后,List.addAll() 而不是 List.add(object) 并进行了此更正,我的不好,令人惊讶的是,一切都按预期的理论预期工作,一切都在其领域内,它有效。

所以很简单。您不需要做任何特别的事情来拆分列表列表。 拆分器将遍历列表并拆分出各个列表。然后您可以获取这些列表并处理它们并转发它们。愚蠢的我认为成熟的 Camel Splitter EIP 表现得很奇怪,它正在做它应该做的事情。

这是最终结果。 (感谢 burki 和其他人的帮助)

    <route autoStartup="true" id="core.fleet.asset.splitterRoute">
        <from id="_from4" uri="{{fileEnrichmentEndpoint}}"/>
        <process id="_process4" ref="assetCollectorProcessor"/>
        <process id="_process5" ref="fleetAssetSplitter"/>
        <split id="fs1">
            <simple>${body}</simple>
            <log id="lfs1" message="Original Body: ${body}"/>
            <process id="pfs1" ref="fileSplitter" />
            <to id="seda:fs1" uri="seda:fs1"/>
        </split>
    </route>

我将文件名隐藏在位置 -0- 的内部列表列表中,所以我们只需提取文件名,设置 CamelFileName,稍微修改数据并将其发送到交换。

    log.info("File Splitter :: Start");

    List<String> pl = (List<String>) exchange.getIn().getBody(List.class);
    log.info("File Pay Load: " + pl);

    fName = pl.get(0);  //get file name
    exchange.getIn().setHeader("CamelFileName", fName);
    pl.remove(0);
    log.debug("**** serviceRecords  ****");
    Iterator<String> pitr = pl.iterator(); 
    while ( pitr.hasNext()) {
          log.debug(pitr.next());
      }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(baos);
    for (String record : pl) {
        out.writeBytes(record + System.lineSeparator());
    }
    out.flush();
    exchange.getIn().setBody(baos.toByteArray());
    out.close();

    log.info("File Splitter :: Finish");

你只需要在RouterBuilder配置中拆分两次

from("direct:split")
    .split(body())
    .split(body())
    .log("Message part: ${body}")
    .to("mock:end");