Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ApacheCamel与Json数组拆分_Json_Apache Camel_Jbossfuse - Fatal编程技术网

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

我有一个camel应用程序,它从一个最大13000大小的jms队列接收json数组请求,json数组请求的结构如下所示。我想用一个5人的组对json数组进行流式处理和拆分。 例如,如果我收到一个大小为100的json数组,我希望将其分组为5个,并将其拆分为20个请求。 是否有内置的camel功能来对json数组进行分组和拆分,还是需要编写自定义拆分器

我使用的是camel 2.17版本

示例json数组:

[{
    "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");