Json 序列化、反序列化;重複或迴圈使用時注意事項

del88發表於2024-07-29

Json序列化問題

public class Test2 {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        PluginSdkModel pluginSdkModel = new PluginSdkModel();

        for (int i = 0; i < 3; i++) {
            pluginSdkModel.setSdkId(123L);
            if(i == 1){
                pluginSdkModel.setModelDesc("wokao");
            }
            System.out.println(objectMapper.writeValueAsString(pluginSdkModel));
        }
    }
}

輸出:

{"sdkId":123}
{"sdkId":123,"modelDesc":"wokao"}
{"sdkId":123,"modelDesc":"wokao"}

可以看到 第三個結果頁輸出了 modeDesc,原因是 序列化的時候,是把 物件的值 序列化成字串,無法先把物件的值清空,所以 序列化 每次 初始化 object 是不現實的,也是無法 解決的問題;需要開發人員自己 最佳化程式碼來解決,比如上面的 程式碼 可以修改下:

        for (int i = 0; i < 3; i++) {
            pluginSdkModel.setSdkId(123L);
            if(i == 1){
                pluginSdkModel.setModelDesc("wokao");
            }else { //這裡加上 else 就可以解決 這個問題,否則 json框架是無法解決的
                pluginSdkModel.setModelDesc(null);
            }
            System.out.println(objectMapper.writeValueAsString(pluginSdkModel));
        }

Json 反序列化問題

序列化時,無法 先把 物件的值 修改成 null,再序列化;那麼反序列化呢,發序列化 字串 ---> object的過程,是可以先把 object清空,然後在序列化的;

Jackson 也 如我們預想的那樣,做了這件事,這樣可以有助於 最大化 幫住開發者減少bug;

public class Test {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        PluginSdkModel pluginSdkModel = new PluginSdkModel();

        String json1 = "{\"sdkId\":123}";
        String json2 = "{\"sdkId\":123,\"modelDesc\":\"wokao\"}";

        for (int i = 0; i < 2; i++) {
            pluginSdkModel = objectMapper.read(json2, PluginSdkModel.class);

            System.out.println(objectMapper.writeValueAsString(pluginSdkModel));

            pluginSdkModel = objectMapper.readValue(json1, PluginSdkModel.class);

            System.out.println(objectMapper.writeValueAsString(pluginSdkModel));
        }
    }
}

輸出:

{"sdkId":123,"modelDesc":"wokao"}
{"sdkId":123}
{"sdkId":123,"modelDesc":"wokao"}
{"sdkId":123}

可以看到 objectMapper.readValue(json2, PluginSdkModel.class); 時,每次 產生一個 全新的 pluginSdkModel,在Java裡 是 記憶體自動管理的,可以這麼搞,在Delphi裡 不方便這麼搞,但是 可以 反序列化時,清空 源 object 裡的 每一個欄位;從而幫助開發者減少bug,實現與Java裡 一樣的效果;

相關文章