fastjson 1.2.0之后的版本支持JSONPath。这是一个很强大的功能,可以在java框架中当作对象查询语言(OQL)来使用。
package com.alibaba.fastjson;
public class JSONPath {
// 求值,静态方法
public static Object eval(Object rootObject, String path);
// 计算Size,Map非空元素个数,对象非空元素个数,Collection的Size,数组的长度。其他无法求值返回-1
public static int size(Object rootObject, String path);
// 是否包含,path中是否存在对象
public static boolean contains(Object rootObject, String path) { }
// 是否包含,path中是否存在指定值,如果是集合或者数组,在集合中查找value是否存在
public static boolean containsValue(Object rootObject, String path, Object value) { }
// 修改制定路径的值,如果修改成功,返回true,否则返回false
public static boolean set(Object rootObject, String path, Object value) {}
// 在数组或者集合中添加元素
public static boolean array_add(Object rootObject, String path, Object... values);
}
建议缓存JSONPath对象,这样能够提高求值的性能。
JSONPATH | 描述 |
---|---|
$ | 表示根元素 |
@ | 当前元素 |
. or [] | 子元素 |
n/a | 父元素 |
.. | 递归下降,JSONPath是从E4X借鉴的。 |
* | 通配符,表示所有的元素 |
?() | 应用过滤表示式 |
[num] | 数组访问,其中num是数字,可以是负数。例如$[0].leader.departments[-1].name |
[num0,num1,num2…] | 数组多个元素访问,其中num是数字,可以是负数,返回数组中的多个元素。例如$[0,3,-2,5] |
[start:end] | 数组范围访问,其中start和end是开始小表和结束下标,可以是负数,返回数组中的多个元素。例如$[0:5] |
[start:end:step] | 数组范围访问,其中start和end是开始小表和结束下标,可以是负数;step是步长,返回数组中的多个元素。例如$[0:5:2] |
[ ?(key) ] | 对象属性非空过滤,例如$.departs[?(name)] |
[ key > 123] | 数值类型对象属性比较过滤,例如$.departs[id >= 123],比较操作符支持=,!=,>,>=,<,<= |
[ key = ‘123’] | 字符串类型对象属性比较过滤,例如$.departs[name = ‘123’],比较操作符支持=,!=,>,>=,<,<= |
[ key like ‘aa%’] | 字符串类型like过滤,例如$.departs[name like ‘sz*’],通配符只支持% 支持not like |
[ key rlike ‘regexpr’] | 字符串类型正则匹配过滤,例如departs[name like ‘aa(.)*’],正则语法为jdk的正则语法,支持not rlike |
[ key in (‘v0’, ‘v1’)] | IN过滤, 支持字符串和数值类型。例如: $.departs[name in (‘wenshao’,’Yako’)],$.departs[id not in (101,102)] |
[ key between 234 and 456] | BETWEEN过滤, 支持数值类型,支持not between。例如: $.departs[id between 101 and 201],$.departs[id not between 101 and 201] |
length() 或者 size() | 数组长度。例如$.values.size() 支持类型java.util.Map和java.util.Collection和数组 |
[‘key’] | 属性访问。例如$[‘name’] |
[‘key0’,’key1’] | 多个属性访问。例如$[‘id’,’name’] |
示例对象:
package json.fastjson.jsonpath;
public class Entity {
private Integer id;
private String name;
private Object value;
public Entity(Integer id, String name, Object value) {
super();
this.id = id;
this.name = name;
this.value = value;
}
public Integer getId() {
return id;
}
public Object getValue() {
return value;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setValue(Object value) {
this.value = value;
}
@Override
public String toString() {
return "Entity [id=" + id + ", name=" + name + ", value=" + value + "]";
}
}
测试类:
package json.fastjson.jsonpath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONPath;
@SuppressWarnings("rawtypes")
public class TestJSONPath {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List entities = new ArrayList();
Entity entity1 = new Entity(1, "挖坑埋你1", "CSDN1");
Entity entity2 = new Entity(2, "挖坑埋你2", "CSDN2");
Entity entity3 = new Entity(3, "挖坑埋你3", "CSDN3");
entities.add(entity1);
entities.add(entity2);
entities.add(entity3);
System.out.println("\n------读取对象中的值---------------------------------------------------------");
System.out.println("JSONPath.eval(entity, \"$.value\") = " + JSONPath.eval(entity1, "$.value"));
System.out.println("JSONPath.contains(entity, \"$.value\") = " + JSONPath.contains(entity1, "$.value"));
System.out.println("JSONPath.containsValue(entity, \"$.id\", 123) = " + JSONPath.containsValue(entity1, "$.id", 123));
System.out.println("JSONPath.containsValue(entity, \"$.value\", entity.getValue()) = " + JSONPath.containsValue(entity1, "$.value", entity1.getValue()));
System.out.println("JSONPath.size(entity, \"$\") = " + JSONPath.size(entity1, "$"));
System.out.println("JSONPath.size(new Object[], \"$\") = " + JSONPath.size(new Object[5], "$"));
System.out.println("\n------读取集合多个元素的某个属性:JSONPath.eval(entities, \"$.name\")-------------");
List names = (List) JSONPath.eval(entities, "$.name"); // 返回enties的所有名称
System.out.println("$.name = " + names);
System.out.println("\n------返回集合中多个元素:JSONPath.eval(entities, \"[1,2]\")--------------------");
List result = (List) JSONPath.eval(entities, "[1,2]"); // 返回下标为1和2的元素
System.out.println("[1,2] = " + result);
System.out.println("\n------按范围返回集合的子集:JSONPath.eval(entities, \"[0:2]\")-------------------");
result = (List) JSONPath.eval(entities, "[0:2]"); // 返回下标从0到2的元素
System.out.println("[0:2] = " + result);
System.out.println("\n------通过条件过滤,返回集合的子集:JSONPath.eval(entities, \"[id in (1)]\")-------");
result = (List) JSONPath.eval(entities, "[id in (1)]");
System.out.println("[id in (1)] = " + result);
System.out.println("\n------根据属性值过滤条件判断是否返回对象--------------------------------------------");
System.out.println("[id = 1] = " + JSONPath.eval(entity1, "[id = 1]"));
System.out.println("[id = 1002] = " + JSONPath.eval(entity1, "[id = 1002]"));
System.out.println("\n------修改对象:JSONPath.set(entity1, \"id\", 123456);//将id字段修改为123456-----");
JSONPath.set(entity1, "id", 123456); // 将id字段修改为123456
System.out.println("entity1.getId().intValue()=" + entity1.getId().intValue());
System.out.println("\n------集合或数组属性添加元素-----------------------------------------------------");
JSONPath.set(entity1, "value", new ArrayList()); // 将value字段赋值为长度为0的集合
System.out.println("entity1=" + entity1);
JSONPath.arrayAdd(entity1, "value", 1, 2, 3); // 将value字段的集合添加元素1,2,3
System.out.println("entity1=" + entity1);
System.out.println("\n------操作复杂对象:JSONPath.eval(root, \"$..id\")-----------------------------");
Map root = Collections.singletonMap("company", //
Collections.singletonMap("departs", //
Arrays.asList( //
Collections.singletonMap("id", 1001), //
Collections.singletonMap("id", 1002), //
Collections.singletonMap("id", 1003) //
) //
));
List
输出结果:
------读取对象中的值---------------------------------------------------------
JSONPath.eval(entity, "$.value") = CSDN1
JSONPath.contains(entity, "$.value") = true
JSONPath.containsValue(entity, "$.id", 123) = false
JSONPath.containsValue(entity, "$.value", entity.getValue()) = true
JSONPath.size(entity, "$") = 3
JSONPath.size(new Object[], "$") = 5
------读取集合多个元素的某个属性:JSONPath.eval(entities, "$.name")-------------
$.name = ["挖坑埋你1","挖坑埋你2","挖坑埋你3"]
------返回集合中多个元素:JSONPath.eval(entities, "[1,2]")--------------------
[1,2] = [Entity [id=2, name=挖坑埋你2, value=CSDN2], Entity [id=3, name=挖坑埋你3, value=CSDN3]]
------按范围返回集合的子集:JSONPath.eval(entities, "[0:2]")-------------------
[0:2] = [Entity [id=1, name=挖坑埋你1, value=CSDN1], Entity [id=2, name=挖坑埋你2, value=CSDN2], Entity [id=3, name=挖坑埋你3, value=CSDN3]]
------通过条件过滤,返回集合的子集:JSONPath.eval(entities, "[id in (1)]")-------
[id in (1)] = [{"id":1,"name":"挖坑埋你1","value":"CSDN1"}]
------根据属性值过滤条件判断是否返回对象--------------------------------------------
[id = 1] = Entity [id=1, name=挖坑埋你1, value=CSDN1]
[id = 1002] = null
------修改对象:JSONPath.set(entity1, "id", 123456);//将id字段修改为123456-----
entity1.getId().intValue()=123456
------集合或数组属性添加元素-----------------------------------------------------
entity1=Entity [id=123456, name=挖坑埋你1, value=[]]
entity1=Entity [id=123456, name=挖坑埋你1, value=[1, 2, 3]]
------操作复杂对象:JSONPath.eval(root, "$..id")-----------------------------
$..id = [1001, 1002, 1003]