我创建了一个读取csv文件的处理器,该文件包含具有不同字段数的行。生产者的构造函数获取一个整数列表,告诉它哪些行是感兴趣的(例如,包含13或65个字段的行)。
对于每个字段计数,输出应该是一个字节[] - 所以我将有一个字节[],其中所有行包含13个字段,另一个包含所有包含65个字段的行。
我以为我可以为每个块创建一个新的交换,并设置一个标题值“fieldCount”。此处理器的输出将进入choice()。when(header ...)route - 将每个块路由到不同的端点集。
但如何创建新的交流?我阅读了this并以这种方式获得了制作人模板ProducerTemplate producer = exchange.getContext().createProducerTemplate();
,但我总是得到defaultEndpoint must be specified
。但我的处理器不是也不应该知道任何端点。什么是“违约点”?如何正确设置?
我也研究过split() - 模式,但这似乎对我的情况没什么帮助。有了它我可以改变我的处理器发出List>并且只是拆分但是选择/当部分更复杂时,或者我需要第二个处理器来创建一个带有每个Map的标头集的byte []。
那么这里最好的方法是什么?
答案 0 :(得分:2)
我认为最简单的方法是:
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("file://file.csv")
.split(body(String.class).tokenize("\n"))
.processor(new FieldCountHeaderProcessor())
.aggregate(header("fieldCount"))
.processor(new ByteArrayConverterProcessor())
.choice()
.when(header("fieldCount").isEqualTo("13")).to("direct:ENDPOINT_FOR_13_FIELDS")
.when(header("fieldCount").isEqualTo("65")).to("direct:ENDPOINT_FOR_65_FIELDS")
.endChoice();
}
}
您只需要实施FieldCountHeaderProcessor
和ByteArrayConverterProcessor
。
您还可以实施ByteArrayAggregationStrategy
(请参阅AggragationStrategy
),该byte[]
会直接汇总到ByteArrayConverterProcessor
,从而无需使用public class MyRouteBuilderWithAggregationStrategy extends RouteBuilder {
@Override
public void configure() throws Exception {
from("file://file.csv")
.split(body(String.class).tokenize("\n"))
.processor(new FieldCountHeaderProcessor())
.aggregate(header("fieldCount"), new ByteArrayAggregationStrategy())
.choice()
.when(header("fieldCount").isEqualTo("13")).to("direct:ENDPOINT_FOR_13_FIELDS")
.when(header("fieldCount").isEqualTo("65")).to("direct:ENDPOINT_FOR_65_FIELDS")
.endChoice();
}
}
。例如:
{{1}}
答案 1 :(得分:0)
同时我创建了另一个同样有效的解决方案:
@Override
public void configure() throws Exception {
from(DIRECT_IN).process(new MyProcessor(Lists.newArrayList(FIELD_COUNT_1, FIELD_COUNT_2))).split().body().choice()
.when(new CheckFieldCount(FIELD_COUNT_1))
.to(MOCK_FIELD_COUNT1)
.when(new CheckFieldCount(FIELD_COUNT_2))
.to(MOCK_FIELD_COUNT2)
.otherwise()
.to(MOCK_NOT_RELEVANT);
}
" MyProcessor"处理具有不同字段计数的csv-byte []到List。 " CsvBlock"是一个包含fieldCount(int)和data(byte [])的原始类。 " CheckFieldCount"实现谓词它只是在交换数据中检查给定的int。 在这种情况下,CsvBlock被发送到mock。对于我的真实代码,我需要另一个处理器从CsvBlock中提取数据(原始代码,但另一个类)。 乍一看,我认为里卡多的方式更好,但这对我来说意味着更多的工作。