踩坑系列之--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)方法,如下圖

    1762862-273cfdb4d56c88b2.jpeg
    截屏2020-02-29下午9.21.01.png
  • 2.1.2 代碼問題分析

    • 如上圖所示,values變量中存儲了json的值爲key,JsonPath爲value,這種情況下,兩個boolean類型的json key,value都爲true,那麼執行到圖中代碼的571行時,p != null 爲true,進入圖中畫紅線框的地方,如下圖


      1762862-5aa301b09a464e44.jpeg
      截屏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基礎類型,就不會出現上述問題,完美

轉載請註明出處 阿布的夏天

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章