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基礎類型,就不會出現上述問題,完美
轉載請註明出處 阿布的夏天