json笔记

发布于:2025-02-11 ⋅ 阅读:(26) ⋅ 点赞:(0)

1、json的组成

        JSON是一个标记符序列。这套标记符包括:构造字符、字符串、数字和字面值(false, true, null)

1.1 构造字符

        六个构造字符:

  • 左方括号  [

  • 右方括号 ]

  • 左大括号 {

  • 右大括号 }

  • 冒号 :

  • 逗号 ,

1.2 JSON值

        json值包括:对象、数组、字符串、字面值(true,false,null)

1.2.1 对象

        由花括号括起来,逗号分割的成员构成,成员是字符串键和上面所说的JSON值构成 

{"name":"jery", "age":18, "sex":"男"}

1.2.2 数组

        由方括号括起来的一组JSON值构成

示例1:一组数字组成的数组

[1, 2, 3, 4, 5, 6, 7, 8]

示例2:一组对象组成的数组

[

        {"name":"jery", "age":18, "sex":"男"},

        {"name":"lina", "age":16, "sex":"女"}

]

1.2.3 字符串、数字和 字面值

下面示例中的name的值为字符串,age的值为数字,isStudent的值为false。

{

        "name":"jery",

        "age":4,

        "isStudent":false

}

2、 JsonPath

        很多时候我们拿到其他模块的json字符串,如果不存在共享的java实体类定义,可能会直接使用JsonObject之类的动态对象类承接这份数据。这时候对于很深的的属性取值是非常复杂的,例如:

public class JsonTest {
    @Test
    public void getJsonObjectValueTest() {
        String json = "{\"a\":{\"b\":{\"c\":{\"d\":\"我是d的值\"}}}}";
        System.out.println(getJsonObjectValue(json));
    }

    private String getJsonObjectValue(String jsonStr) {
        JSONObject json = JSONObject.parseObject(jsonStr);
        JSONObject a = json.getJSONObject("a");
        if (a != null) {
            JSONObject b = a.getJSONObject("b");
            if (b != null) {
                JSONObject c = b.getJSONObject("c");
                if (c != null) {
                    return c.getString("d");
                }
            }
        }
        return null;
    }

}

        使用jsonpath可以变的简单:

    @Test
    public void getValueByPathTest() {
        String json = "{\"a\":{\"b\":{\"c\":{\"d\":\"我是d的值\"}}}}";
        Object value = JSONPath.compile("$.a.b.c.d").eval(json);
        System.out.println(value);
    }

2.1 基本语法

        参考 https://github.com/alibaba/fastjson/wiki/JSONPath

FastJson 解析神器JsonPath 使用手册-CSDN博客

JSONPATH 描述
$ 根对象,例如$.name
@ 文档当前节点对象,类似于java 中的 this 字段
[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 rlike '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和数组
keySet() 获取Map的keySet或者对象的非空属性名称。例如$.val.keySet()
支持类型:Map和普通对象
不支持:Collection和数组(返回null)
. 属性访问,例如$.name
.. deepScan属性访问,例如$..name
* 对象的所有属性,例如$.leader.*
['key'] 属性访问。例如$['name']
['key0','key1'] 多个属性访问。例如$['id','name']
  • $:表示JSON数据的根对象。
  • .[]:用于访问对象的属性或数组的元素。例如,$.name 或 $[‘name’] 都可以访问根对象中的 ‘name’ 属性。
  • :表示递归下降,用于查找所有级别的属性。
  • ?():应用一个过滤表达式来过滤数组中的元素。例如,$?(@.age>18) 将选择所有年龄大于18的对象。
  • []:在属性名或数组索引位置使用,表示选择所有元素。例如,$.students[*].name 将选择所有学生的名字。
  • -101n:用作数组索引时,表示从最后一个元素开始计数。例如,$.students[-1].name 将选择最后一个学生的名字。

2.1 关于JSONPath.eval中第三个参数ignoreNullValue

        在jsonPath中,如果要获取的参数是列表中的元素(返回的是列表),会默认过滤掉null的取值,示例:

    public void jsonTestDefaultIgnoreNull() {
        String jsonStr = "{'store':{'book':[" +
                "{'category':'reference','author':'Nigel Rees','title':'Sayings of the Century','price':8.95}," +
                "null," +
                "{'category':null,'author':'Evelyn Waugh','title':'Sword of Honour','price':12.99}]," +
                "'bicycle':{'color':'red','price':19.95}}}\n";
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        System.out.println("Book数目:" + JSONPath.eval(jsonObject, "$.store.book.size()"));
        System.out.println("books:" + JSONPath.eval(jsonObject, "$.store.book"));
        System.out.println("categories:" + JSONPath.eval(jsonObject, "$.store.book.category"));
        System.out.println("categories:" + JSONPath.eval(jsonObject, "$.store.book[*].category"));
    }

执行结果为(categories列表不包含第2个null book和第三个book的null categoriy:

Book数目:3
books:[{"author":"Nigel Rees","price":8.95,"category":"reference","title":"Sayings of the Century"},null,{"author":"Evelyn Waugh","price":12.99,"title":"Sword of Honour"}]
categories:["reference"]
categories:["reference"]

        添加ignoreNullValue参数并设置为false后,返回的categories会包含后面两个book的null:

    public void jsonTestNotIgnoreNull() {
        String jsonStr = "{'store':{'book':[" +
                "{'category':'reference','author':'Nigel Rees','title':'Sayings of the Century','price':8.95}," +
                "null," +
                "{'category':null,'author':'Evelyn Waugh','title':'Sword of Honour','price':12.99}]," +
                "'bicycle':{'color':'red','price':19.95}}}\n";
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        System.out.println("Book数目:" + JSONPath.eval(jsonObject, "$.store.book.size()", false));
        System.out.println("books:" + JSONPath.eval(jsonObject, "$.store.book[*]", false));
        System.out.println("categories:" + JSONPath.eval(jsonObject, "$.store.book[*].category", false));
        System.out.println("categories:" + JSONPath.eval(jsonObject, "$.store.book.category", false));
    }

        执行结果为:

Book数目:3
books:[{"author":"Nigel Rees","price":8.95,"category":"reference","title":"Sayings of the Century"},null,{"author":"Evelyn Waugh","price":12.99,"title":"Sword of Honour"}]
categories:["reference",null,null]
categories:["reference",null,null]

        切换fastjson2后,默认行为和fastjson相同,eval没有提供包含参数ignoreNullValue的接口,如果要实现相同的功能,需要使用:JSONPath.of("$.store.book[*].category", JSONPath.Feature.KeepNullValue),注意,这里如果使用$.store.book.category也会忽略值为null的value。

    public void jsonTestNotIgnoreNull() {
        String jsonStr = "{'store':{'book':[" +
                "{'category':'reference','author':'Nigel Rees','title':'Sayings of the Century','price':8.95}," +
                "null," +
                "{'category':null,'author':'Evelyn Waugh','title':'Sword of Honour','price':12.99}]," +
                "'bicycle':{'color':'red','price':19.95}}}\n";
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        System.out.println("Book数目:" + JSONPath.extract(jsonStr, "$.store.book.size()", JSONPath.Feature.KeepNullValue));
        System.out.println("books:" + JSONPath.extract(jsonStr, "$.store.book[*]", JSONPath.Feature.KeepNullValue));
        System.out.println("categories:" + JSONPath.of("$.store.book.category", JSONPath.Feature.KeepNullValue).eval(jsonObject));
        System.out.println("categories:" + JSONPath.of("$.store.book[*].category", JSONPath.Feature.KeepNullValue).eval(jsonObject));
    }

执行结果为:

Book数目:3
books:[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},null,{"author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]
categories:["reference"]
categories:["reference",null,null]


网站公告

今日签到

点亮在社区的每一天
去签到