踩坑系列之--Fastjson JSONPath解析Boolean类型翻车了

1. 现象

不上代码的例子都是耍流氓,咱们直接上代码,有以下两个json串,第一个json比第二个json多了两个boolean类型值,以及一个string类型值;
{
    "boolean1":true,
    "boolean2":false,
    "boolean3":true,// 比下面的json多的
    "boolean4":true,// 比下面的json多的
    "name":"str",
    "name1":"str"
}

{
    "boolean1":true,
    "boolean2":false,
    "name":"str"
}
public static void main(String[] args) {
        JSONObject sourceJson = JSON.parseObject("{\n" +
                "\t\"boolean1\":true,\n" +
                "\t\"boolean2\":false,\n" +
                "\t\"boolean3\":true,\n" +
                "\t\"boolean4\":true,\n" +
                "\t\"name\":\"str\",\n" +
                "\t\"name1\":\"str\"\n" +
                "}");

        // 初始配置中,新增的字段添加的库中
        Map<String, Object> paths = JSONPath.paths(sourceJson);
        System.out.println(JSON.toJSONString(paths));

        JSONObject destJson = JSON.parseObject("{\n" +
                "\t\"boolean1\":true,\n" +
                "\t\"boolean2\":false,\n" +
                "\t\"name\":\"str\"\n" +
                "}");

        for (Map.Entry<String, Object> stringObjectEntry : paths.entrySet()) {
            if(stringObjectEntry.getValue() instanceof JSONObject || stringObjectEntry.getValue() instanceof JSONArray){
                continue;
            }
            if (!JSONPath.contains(destJson, stringObjectEntry.getKey())) {
                JSONPath.set(destJson, stringObjectEntry.getKey(), stringObjectEntry.getValue());
                System.out.println("key=" + stringObjectEntry.getKey() + " ,value=" + stringObjectEntry.getValue());
            }
        }

        System.out.println(destJson.toJSONString());
    }

1.1 目标

运行上述代码,这里目标是经过JSONPath解析第一个json,而后对比第二个json中JSONPath,将第一个的多的key,找出来,那正确的状况应该是找出以下几项
{
    "boolean3":true,
    "boolean4":true,
    "name1":"str"
}

1.2 实际状况

  • 1.2.1 代码运行结果以下,能够看到,实际找出的差别键只有两个 boolean3和name1,发现少识别了一个boolean4的key

{"/name":"str","/boolean3":true,"/name1":"str","/boolean2":false,"/":{"boolean2":false,"name":"str","boolean3":true,"boolean1":true,"name1":"str","boolean4":true}}
-----------------
key=/boolean3 ,value=true
key=/name1 ,value=str
-----------------
{"boolean2":false,"name":"str","boolean3":true,"boolean1":true,"name1":"str"}

2. 缘由分析

  • 2.1 源码debug

    从运行结果的第一行输出能够看到,解析第一个json串的JSONPath答应出来后,就已经没有了 boolean4的存在,因此咱们直接debug进去看看到底哪里出了问题??
  • 2.1.1 IDEA断点运行进入JSONPath.paths(sourceJson)方法,以下图

    截屏2020-02-29下午9.21.01.png

  • 2.1.2 代码问题分析

    • 如上图所示,values变量中存储了json的值为key,JsonPath为value,这种状况下,两个boolean类型的json key,value都为true,那么执行到图中代码的571行时,p != null 为true,进入图中画红线框的地方,以下图
    • 截屏2020-02-29下午9.28.28.png
    • 从上图能够看到,boolean4的path因为Boolean不属于String,Number,Date,UUID,致使被return了,问题缘由找到了,就是因为代码中没有把Boolean当作是基础类型致使的,我也去github中寻找是否存在此issue,果真有github issue

3. 解决方法

  • 3.1 版本升级

    • 目前最新的版本1.2.62依然存在此问题因此没法经过升级来解决
  • 3.2 曲线救国

    • 咱们能够把Boolean类型的json的value值都加上"",这样就变成了String基础类型,就不会出现上述问题,完美

转载请注明出处 阿布的夏天java

相关文章
相关标签/搜索