使用骆驼拆分器拆分列表列表
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");
我创建了许多 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");