簡體   English   中英

使用駱駝拆分器拆分列表列表

[英]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 路線,它在嘗試不同的事情時處於混亂狀態。 沒有一個工作。 必須有一個技巧來拆分列表列表。

    <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>

從列表列表的拆分生成的多個文件。

您可以根據需要使用 JavaBean 來實現嵌套的 Splitter 邏輯。

如果標准的Splitter EIP不能做你想要的,你可以用一個 bean 告訴他如何拆分你的消息的有效負載。

因此,如果您將 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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM