fastJson 之 JSONPath使用

前端之家收集整理的这篇文章主要介绍了fastJson 之 JSONPath使用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1. JSONPath介绍

官网地址: https://github.com/alibaba/fastjson/wiki/JSONPath

fastjson 1.2.0之后的版本支持JSONPath。这是一个很强大的功能,可以在java框架中当作对象查询语言(OQL)来使用。

2. API

  1. package com.alibaba.fastjson;
  2.  
  3. public class JSONPath {
  4. // 求值,静态方法
  5. public static Object eval(Object rootObject,String path);
  6.  
  7. // 计算Size,Map非空元素个数,对象非空元素个数,Collection的Size,数组的长度。其他无法求值返回-1
  8. public static int size(Object rootObject,String path);
  9.  
  10. // 是否包含,path中是否存在对象
  11. public static boolean contains(Object rootObject,String path) { }
  12.  
  13. // 是否包含,path中是否存在指定值,如果是集合或者数组,在集合中查找value是否存在
  14. public static boolean containsValue(Object rootObject,String path,Object value) { }
  15.  
  16. // 修改制定路径的值,如果修改成功,返回true,否则返回false
  17. public static boolean set(Object rootObject,Object value) {}
  18.  
  19. // 在数组或者集合中添加元素
  20. public static boolean array_add(Object rootObject,Object... values);
  21. }

建议缓存JSONPath对象,这样能够提高求值的性能

3. 支持语法

JSONPATH 描述
</td><td> .name
[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过滤,支持字符串和数值类型
例如:
@H_404_268@.departs[namein(wenshao,Yako)]<br/@H_456_404@> .departs[id not in (101,102)]
[key between 234 and 456] BETWEEN过滤,支持数值类型,支持not between
例如:
.departs[idbetween101and201]<br/> @H_404_513@.departs[id between 101 and 201]
.departs[id not between 101 and 201]
length() 或者 size() 数组长度。例如$.values.size()
支持类型java.util.Map和java.util.Collection和数组
. 属性访问,例如$.name
.. deepScan属性访问,例如$..name
* 对象的所有属性,例如$.leader.*
[‘key’] 属性访问。例如$[‘name’]
[‘key0’,’key1’] 多个属性访问。例如$[‘id’,’name’]

以下两种写法的语义是相同的:

  1. $.store.book[0].title

  1. $['store']['book'][0]['title']

4. 语法示例

JSONPath 语义
$ 根对象
$[-1] 最后元素
$[:-2] 第1个至倒数第2个
$[1:] 第2个之后所有元素
$[1,2,3] 集合中1,3个元素

5. API 示例

5.1 例1

  1. public void test_entity() throws Exception {
  2. Entity entity = new Entity(123,new Object());
  3.  
  4. Assert.assertSame(entity.getValue(),JSONPath.eval(entity,"$.value"));
  5. Assert.assertTrue(JSONPath.contains(entity,"$.value"));
  6. Assert.assertTrue(JSONPath.containsValue(entity,"$.id",123));
  7. Assert.assertTrue(JSONPath.containsValue(entity,"$.value",entity.getValue()));
  8. Assert.assertEquals(2,JSONPath.size(entity,"$"));
  9. Assert.assertEquals(0,JSONPath.size(new Object[],"$"));
  10. }
  11.  
  12. public static class Entity {
  13. private Integer id;
  14. private String name;
  15. private Object value;
  16.  
  17. public Entity() {}
  18. public Entity(Integer id,Object value) { this.id = id; this.value = value; }
  19. public Entity(Integer id,String name) { this.id = id; this.name = name; }
  20. public Entity(String name) { this.name = name; }
  21.  
  22. public Integer getId() { return id; }
  23. public Object getValue() { return value; }
  24. public String getName() { return name; }
  25.  
  26. public void setId(Integer id) { this.id = id; }
  27. public void setName(String name) { this.name = name; }
  28. public void setValue(Object value) { this.value = value; }
  29. }

5.2 例2

读取集合多个元素的某个属性

  1. List<Entity> entities = new ArrayList<Entity>();
  2. entities.add(new Entity("wenshao"));
  3. entities.add(new Entity("ljw2083"));
  4.  
  5. List<String> names = (List<String>)JSONPath.eval(entities,"$.name"); // 返回enties的所有名称
  6. Assert.assertSame(entities.get(0).getName(),names.get(0));
  7. Assert.assertSame(entities.get(1).getName(),names.get(1));

5.3 例3

返回集合中多个元素

  1. List<Entity> entities = new ArrayList<Entity>();
  2. entities.add(new Entity("wenshao"));
  3. entities.add(new Entity("ljw2083"));
  4. entities.add(new Entity("Yako"));
  5.  
  6. List<Entity> result = (List<Entity>)JSONPath.eval(entities,"[1,2]"); // 返回下标为1和2的元素
  7. Assert.assertEquals(2,result.size());
  8. Assert.assertSame(entities.get(1),result.get(0));
  9. Assert.assertSame(entities.get(2),result.get(1));

5.4 例4

按范围返回集合的子集

  1. List<Entity> entities = new ArrayList<Entity>();
  2. entities.add(new Entity("wenshao"));
  3. entities.add(new Entity("ljw2083"));
  4. entities.add(new Entity("Yako"));
  5.  
  6. List<Entity> result = (List<Entity>)JSONPath.eval(entities,"[0:2]"); // 返回下标从0到2的元素
  7. Assert.assertEquals(3,result.size());
  8. Assert.assertSame(entities.get(0),result.get(0));
  9. Assert.assertSame(entities.get(1),result.get(1));
  10. Assert.assertSame(entities.get(2),result.get(1));

5.5 例5

通过条件过滤,返回集合的子集

  1. List<Entity> entities = new ArrayList<Entity>();
  2. entities.add(new Entity(1001,"ljw2083"));
  3. entities.add(new Entity(1002,"wenshao"));
  4. entities.add(new Entity(1003,"yakolee"));
  5. entities.add(new Entity(1004,null));
  6.  
  7. List<Object> result = (List<Object>) JSONPath.eval(entities,"[id in (1001)]");
  8. Assert.assertEquals(1,result.get(0));

5.6 例6

根据属性值过滤条件判断是否返回对象,修改对象,数组属性添加元素

  1. Entity entity = new Entity(1001,"ljw2083");
  2. Assert.assertSame(entity,"[id = 1001]"));
  3. Assert.assertNull(JSONPath.eval(entity,"[id = 1002]"));
  4.  
  5. JSONPath.set(entity,"id",123456); //将id字段修改为123456
  6. Assert.assertEquals(123456,entity.getId().intValue());
  7.  
  8. JSONPath.set(entity,"value",new int[0]); //将value字段赋值为长度为0的数组
  9. JSONPath.arrayAdd(entity,1,2,3); //将value字段的数组添加元素1,3

5.7 例7

  1. Map root = Collections.singletonMap("company",//
  2. Collections.singletonMap("departs",//
  3. Arrays.asList( //
  4. Collections.singletonMap("id",1001),//
  5. Collections.singletonMap("id",1002),1003) //
  6. ) //
  7. ));
  8.  
  9. List<Object> ids = (List<Object>) JSONPath.eval(root,"$..id");
  10. assertEquals(3,ids.size());
  11. assertEquals(1001,ids.get(0));
  12. assertEquals(1002,ids.get(1));
  13. assertEquals(1003,ids.get(2));

具体用例测试请看下面:

  1. /** * @author itguang * @create 2017-12-10 10:03 **/
  2.  
  3. @RunWith(SpringRunner.class)
  4. @SpringBootTest
  5. @Slf4j
  6. public class JSONpathControllerTest {
  7.  
  8.  
  9. @Test
  10. public void test() {
  11.  
  12. User user = new User("itguang","123456","123@qq.com");
  13. String username = (String) JSONPath.eval(user,"$.username");
  14.  
  15. log.info("$.username = {}",username);
  16.  
  17. Entity entity = new Entity(123,user);
  18. User user1 = (User) JSONPath.eval(entity,"$.value");
  19. log.info("user={}",user1.toString());
  20.  
  21.  
  22. }
  23.  
  24.  
  25. @Test
  26. public void test2() {
  27.  
  28. User user = new User("itguang","123@qq.com");
  29. Entity entity = new Entity(123,user);
  30.  
  31. //判断entity中是否有 data
  32. boolean contains = JSONPath.contains(entity,"$.data");
  33. Assert.assertTrue(contains);
  34.  
  35. //判断 entity.data.username 属性值是否为 itguang
  36. boolean containsValue = JSONPath.containsValue(entity,"$.data.username","itguang");
  37. Assert.assertTrue(containsValue);
  38.  
  39. Assert.assertEquals(2,"$"));
  40.  
  41.  
  42. }
  43.  
  44.  
  45. @Test
  46. public void test3() {
  47.  
  48. List<Entity> entities = new ArrayList<Entity>();
  49. entities.add(new Entity("逻辑"));
  50. entities.add(new Entity("叶文杰"));
  51. entities.add(new Entity("程心"));
  52.  
  53. //返回集合中多个元素
  54. List<String> names = (List<String>) JSONPath.eval(entities,"$.name");
  55. log.info("返回集合中多个元素names={}",names);
  56.  
  57.  
  58. //返回下标 0 和 2 的元素
  59. List<Entity> result = (List<Entity>) JSONPath.eval(entities,"[0,2]");
  60. log.info("返回下标 0 和 2 的元素={}",result);
  61.  
  62. // 返回下标从0到2的元素
  63. List<Entity> result2 = (List<Entity>) JSONPath.eval(entities,"[0:2]");
  64.  
  65. log.info("返回下标从0到2的元素={}",result2);
  66.  
  67.  
  68. }
  69.  
  70.  
  71. @Test
  72. public void test4() {
  73.  
  74. List<Entity> entities = new ArrayList<Entity>();
  75. entities.add(new Entity(1001,"逻辑"));
  76. entities.add(new Entity(1002,"程心"));
  77. entities.add(new Entity(1003,"叶文杰"));
  78. entities.add(new Entity(1004,null));
  79.  
  80. //通过条件过滤,返回集合的子集
  81.  
  82. List<Entity> result = (List<Entity>) JSONPath.eval(entities,"[id in (1001)]");
  83. log.info("通过条件过滤,返回集合的子集={}",result);
  84.  
  85.  
  86. }
  87.  
  88. /** * 使用JSONPrase 解析JSON字符串或者Object对象 * <p> * read(String json,String path)//直接使用json字符串匹配 * <p> * eval(Object rootObject,String path) //直接使用 对象匹配 * <p> * <p> * {"store":{"bicycle":{"color":"red","price":19.95},"book":[{"author":"Nigel Rees","price":8.95,"category":"reference","title":"Sayings of the Century"},{"author":"Evelyn Waugh","price":12.99,"isbn":"0-553-21311-3","category":"fiction","title":"Sword of Honour"}]}} */
  89. @Test
  90. public void test5() {
  91.  
  92.  
  93. String jsonStr = "{\n" +
  94. " \"store\": {\n" +
  95. " \"bicycle\": {\n" +
  96. " \"color\": \"red\",\n" +
  97. " \"price\": 19.95\n" +
  98. " },\n" +
  99. " \"book\": [\n" +
  100. " {\n" +
  101. " \"author\": \"刘慈欣\",\n" +
  102. " \"price\": 8.95,\n" +
  103. " \"category\": \"科幻\",\n" +
  104. " \"title\": \"三体\"\n" +
  105. " },\n" +
  106. " {\n" +
  107. " \"author\": \"itguang\",\n" +
  108. " \"price\": 12.99,\n" +
  109. " \"category\": \"编程语言\",\n" +
  110. " \"title\": \"go语言实战\"\n" +
  111. " }\n" +
  112. " ]\n" +
  113. " }\n" +
  114. "}";
  115.  
  116. JSONObject jsonObject = JSON.parSEObject(jsonStr);
  117.  
  118. log.info(jsonObject.toString());
  119.  
  120. //得到所有的书
  121. List<Book> books = (List<Book>) JSONPath.eval(jsonObject,"$.store.book");
  122. log.info("books={}",books);
  123.  
  124. //得到所有的书名
  125. List<String> titles = (List<String>) JSONPath.eval(jsonObject,"$.store.book.title");
  126. log.info("titles={}",titles);
  127.  
  128. //第一本书title
  129. String title = (String) JSONPath.read(jsonStr,"$.store.book[0].title");
  130. log.info("title={}",title);
  131.  
  132. //price大于10元的book
  133. List<Book> list = (List<Book>) JSONPath.read(jsonStr,"$.store.book[price > 10]");
  134. log.info("price大于10元的book={}",list);
  135.  
  136. //price大于10元的title
  137. List<String> list2 =(List<String>) JSONPath.read(jsonStr,"$.store.book[price > 10].title");
  138. log.info("price大于10元的title={}",list2);
  139.  
  140. //category(类别)为科幻的book
  141. List<Book> list3 = (List<Book>) JSONPath.read(jsonStr,"$.store.book[category = '科幻']");
  142. log.info("category(类别)为科幻的book={}",list3);
  143.  
  144.  
  145. //bicycle的所有属性
  146.  
  147. Collection<String> values = (Collection<String>) JSONPath.eval(jsonObject,"$.store.bicycle.*");
  148.  
  149. log.info("bicycle的所有属性值={}",values);
  150.  
  151.  
  152. //bicycle的color和price属性
  153. List<String> read =(List<String>) JSONPath.read(jsonStr,"$.store.bicycle['color','price']");
  154.  
  155. log.info("bicycle的color和price属性值={}",read);
  156.  
  157.  
  158. }
  159.  
  160.  
  161. }

源码地址: https://github.com/itguang/gitbook-smile/blob/master/springboot-fastjson/fastjson%E4%B9%8BJSONPath%E4%BD%BF%E7%94%A8.md

猜你在找的Json相关文章