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)方法,如下图
-
2.1.2 代码问题分析
- 如上图所示,values变量中存储了json的值为key,JsonPath为value,这种情况下,两个boolean类型的json key,value都为true,那么执行到图中代码的571行时,p != null 为true,进入图中画红线框的地方,如下图
- 从上图可以看到,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基础类型,就不会出现上述问题,完美
2020-06-15 更新,目前最新版本1.2.71已经修复上述问题,请更新食用
转载请注明出处 阿布的夏天