ApacheCamel与Json数组拆分
我有一个camel应用程序,它从一个最大13000大小的jms队列接收json数组请求,json数组请求的结构如下所示。我想用一个5人的组对json数组进行流式处理和拆分。 例如,如果我收到一个大小为100的json数组,我希望将其分组为5个,并将其拆分为20个请求。 是否有内置的camel功能来对json数组进行分组和拆分,还是需要编写自定义拆分器 我使用的是camel 2.17版本 示例json数组:ApacheCamel与Json数组拆分,json,apache-camel,jbossfuse,Json,Apache Camel,Jbossfuse,我有一个camel应用程序,它从一个最大13000大小的jms队列接收json数组请求,json数组请求的结构如下所示。我想用一个5人的组对json数组进行流式处理和拆分。 例如,如果我收到一个大小为100的json数组,我希望将其分组为5个,并将其拆分为20个请求。 是否有内置的camel功能来对json数组进行分组和拆分,还是需要编写自定义拆分器 我使用的是camel 2.17版本 示例json数组: [{ "name": "Ram", "email": "ram@gmail
[{
"name": "Ram",
"email": "ram@gmail.com",
"age": 23
}, {
"name": "Shyam",
"email": "shyam23@gmail.com",
"age": 28
}, {
"name": "John",
"email": "john@gmail.com",
"age": 33
}, {
"name": "Bob",
"email": "bob32@gmail.com",
"age": 41
}, {
"name": "test1",
"email": "test1@gmail.com",
"age": 41
}, {
"name": "test2",
"email": "test2@gmail.com",
"age": 41
}, {
"name": "test3",
"email": "test3@gmail.com",
"age": 41
}, {
"name": "test4",
"email": "test4@gmail.com",
"age": 41
}]
这会奏效的
@Autowired
@EndpointInject(uri = "direct://splitted-queue")
ProducerTemplate producerTemplate;
@Component
class Router extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct://direct-queue").split(ExpressionBuilder.languageExpression("jsonpath","$")).convertBodyTo(String.class).process(new Processor() {
List<String> jsons = new ArrayList<>();
@Override
public void process(Exchange exchange) throws Exception {
jsons.add(exchange.getIn().getBody().toString());
if(jsons.size() == 5) {
producerTemplate.sendBody(jsons);
jsons.clear();
}
}
});
}
@Autowired
@端点注入(uri=”direct://splitted-queue")
ProducerTemplate ProducerTemplate;
@组成部分
类路由器扩展了RouteBuilder{
@凌驾
public void configure()引发异常{
从(”direct://direct-queuesplit(ExpressionBuilder.languageExpression(“jsonpath”、“$”)).convertBodyTo(String.class).process(新处理器(){
List jsons=new ArrayList();
@凌驾
公共作废进程(Exchange)引发异常{
add(exchange.getIn().getBody().toString());
if(jsons.size()==5){
发送体(jsons);
jsons.clear();
}
}
});
}
为此,您需要camel jsonpath依赖项
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jsonpath</artifactId>
<version>2.19.0</version>
</dependency>
org.apache.camel
camel-jsonpath
2.19.0
试试这个
from("{{queue.endpoint}}")
.split().tokenize("},", 5)
.log("Incoming request : ${body} ")
;
您可以尝试以下方法:
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.split().jsonpath("$")
.streaming()
.aggregate(AggregationStrategies.groupedExchange())
.constant("true")
.completionSize(5)
.completionTimeout(1000)
.log("${body}")
.to("mock:result");
}
};
}
如果邮件的大小不是5的倍数,则路由应在聚合前等待1秒并继续。使用您的输入,结果将是两封邮件,分别包含5项和3项:
INFO 5419 --- [ main] route1 : List<Exchange>(5 elements)
INFO 5419 --- [eTimeoutChecker] route1 : List<Exchange>(3 elements)
INFO 5419---[main]路由1:列表(5个元素)
信息5419---[eTimeoutChecker]路由1:列表(3个元素)
可以查看完整的样本
编辑:
根据要求,Spring DSL示例:
<camel:route>
<camel:from uri="direct:start" />
<camel:split streaming="true">
<camel:jsonpath>$</camel:jsonpath>
<camel:aggregate completionSize="5"
completionTimeout="1000" groupExchanges="true">
<camel:correlationExpression>
<camel:constant>true</camel:constant>
</camel:correlationExpression>
<camel:log message="${body}"></camel:log>
<camel:to uri="mock:result"></camel:to>
</camel:aggregate>
</camel:split>
</camel:route>
$
真的
这个json数组是队列中的一条消息吗?你的意思是想将它拆分为多条jms消息吗?嗨,Kiran,是的,我们得到一条jms json数组消息,我们需要拆分为多条消息。上面是一条驼峰路线。你是什么意思?亲爱的Kiran,我是说Spring DSL。你为什么不试试看呢lready也尝试了同样的方法,在我们的例子中,我们需要将一个20000的json数组拆分为20的completionsize。completionTimeout 1000毫秒是否有效,或者我需要重新检查该值?我认为您应该运行一些负载测试来断言该值。不过,1000毫秒是一个神奇的数字。:)Hi Ricardo,我能够将json消息拆分为列表(元素)如何在camel中将其转换为json字符串?我已经这样做了,但不起作用。您可以实现自己的聚合策略,并将每条消息转换为字符串生成器。
public class JSONArraySplitterBean {
public static List<JSONObject> convertToListOfJsonObjects(String input) {
JSONArray array = new JSONArray(input);
return arrayToStream(array).parallel().map(JSONObject.class::cast).collect(Collectors.toList());
}
}
private JSONArraySplitterBean myFunkySplitterBean = new JSONArraySplitterBean();
from("bla")
.split().method(myFunkySplitterBean, "convertToListOfJsonObjects")
.to("bla2");