踩坑系列之--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

相關文章
相關標籤/搜索