Java 解析和处理 json 用哪个开源包最好?

 

Java 中有许多可用的 JSON 库,绝大多数开源包都是将 JSON 完全反序列化为 Java 对象,然后去访问对象中感兴趣的属性值,比如众人皆知的 Jackson、GSON、Genson、FastJson 和 org.json。 还有一类 Json 类库,比如 JsonPATH,Java 中调用特定 DSL 语法,即用 XPath 表达式遍历 JSON 对象,然后在路径的尾端调用最值、平均值、汇总值等函数计算整个 JSON 文档。其实,如果是面向 Json 数据计算的需求,用Open-esProc更方便。但 Open-esProc 和一般 Java 包有所不同,是将数据类型和计算方法封装到一个叫 SPL 的脚本语言中,然后在 Java 程序中调用 SPL 脚本,返回 ResultSet 对象。

先举个简单的例子,文件 EO.json 存储一批员工信息,以及属于员工的多个订单,部分数据如下:

[{
      "_id": {"$oid":   "6074f6c7e85e8d46400dc4a7"},
      "EId": 7,"State":   "Illinois","Dept": "Sales","Name":   "Alexis","Gender": "F","Salary":   9000,"Birthday": "1972-08-16",
      "Orders": [
         {"OrderID":   70,"Client": "DSG","SellerId":   7,"Amount": 288,"OrderDate": "2009-09-30"},
         {"OrderID":   131,"Client": "FOL","SellerId":   7,"Amount": 103.2,"OrderDate": "2009-12-10"}
    ]
}
{
      "_id": {"$oid":   "6074f6c7e85e8d46400dc4a8"},
      "EId": 8,"State": "California", ...
}]

用 SPL 条件查询实现如下:


A

1

=json(file("D:\\data\\EO.json").read())

2

=A1.conj(Orders)

3

=A2.select(Amount>500 &&   Amount<=2000 && like@c(Client,"*bro*"))

上面代码先将Json读为多层的序表对象,再用conj函数合并所有订单,之后用select函数完成条件查询。

这段代码可在esProc IDE中调试执行,存为脚本文件(比如condition.dfx),通过JDBC接口在JAVA中调用,具体代码如下:

package Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class test1 {
    public static void main(String[]   args)throws Exception {
       Class.forName("com.esproc.jdbc.InternalDriver");
       Connection connection   =DriverManager.getConnection("jdbc:esproc:local://");
       Statement statement =   connection.createStatement();
       ResultSet result =   statement.executeQuery("call condition()");
       printResult(result);
       if(connection != null)   connection.close();
    }
…
}

上面的用法类似存储过程,其实 SPL 也支持类似 SQL 的用法,即无须脚本文件,直接将 SPL 嵌入 JAVA 程序,代码如下:

…
ResultSet result = statement.executeQuery("=json(file(\"D:\\data\\EO.json\").read()).conj(Orders).select(Amount>500   && Amount<=3000 && like@c(Client,\"*bro*\"))");
…

SPL 可以轻松实现分组汇总和关联计算,代码如下:


A

B

1

=json(file("D:\\data\\EO.json").read())


2

=A1.conj(Orders)


3

=A2.select(Amount>1000 &&   Amount<=3000 && like@c(Client,"*s*"))

/条件查询

4

=A2.groups(year(OrderDate);sum(Amount))

/分组汇总

5

=A1.new(Name,Gender,Dept,Orders.OrderID,Orders.Client,Orders.Client,Orders.SellerId,Orders.Amount,Orders.OrderDate)

/关联计算

SPL语法表达能力强,经常可以简化多层json的计算,比如:文件JSONstr.jsonrunners字段是子文档,子文档有3个字段:horseIdownerColourstrainer,其中trainer含有下级字段trainerId ownerColours是逗号分割的数组。部分数据如下:

[
   {
      "race": {
            "raceId":"1.33.1141109.2",
            "meetingId":"1.33.1141109"
      },
      ...
        "numberOfRunners": 2,
      "runners":   [
          {     "horseId":"1.00387464",
                "trainer": {
                    "trainerId":"1.00034060"
                },
            "ownerColours":"Maroon,pink,dark blue."
            },
            {   "horseId":"1.00373620",
                "trainer": {
                    "trainerId":"1.00010997"
                },
            "ownerColours":"Black,Maroon,green,pink."
            }
      ]
   },
...
]

现在要按 trainerId分组,统计每组中 ownerColours的成员个数。可用下面的SPL实现本计算。


A

1

=json(file("/workspace/JSONstr.json").read())

2

=A1(1).runners

3

=A2.groups(trainer.trainerId; ownerColours.array().count():times)

SPL 不仅有专用函数读取文件中的 json,也支持读取 MongoDB、Elasticsearch、WebService 等多种数据源中的 Json。比如,连接 MongoDB 计算 Json 数据,参考 用 Java 如何对 MongoDB 执行类似 SQL 的查询?