1. 程式人生 > >記一次使用Jackson對Java物件序列化和反序列化的踩坑經歷

記一次使用Jackson對Java物件序列化和反序列化的踩坑經歷

背景大概是這樣,專案中的兩個服務A和B依賴了同一個common包的Java類,A對該類json序列化,而B對其反序列化。在一次common包升級過程中,這個Java類中增加了一個屬性,由於B其實用不到這個屬性,就只把A給升級打包了,這就導致B在反序列化時出現了一個異常:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field 。

使用程式碼簡單示例一下:

package com.suspect.json.model;


import lombok.*;

@ToString
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    String name;
    Integer age;
    String gender;

}
package com.suspect.json;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.suspect.json.model.Student;
import java.io.IOException;

public class Application {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        String srcJsonString = "{\"number\":\"110119120\",\"name\":\"林志玲\",\"age\":18,\"gender\":\"女\"}";
        Student to = objectMapper.readValue(srcJsonString, Student.class);
        System.out.println(to);

    }
}

可以看出,json串中比Java物件多了一個屬性,這就會導致上述異常。解決方法也很簡單,就是在需要json序列化和反序列化的Java類上增加一個JsonIgnoreProperties註解即可:

package com.suspect.json.model;


import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;

@ToString
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Student {
    String name;
    Integer age;
    String gender;

}

如此,就會在反序列化時忽略未知的屬性,不再出現異常。不過,雖然這種方法可行,但是需要在每個序列化的Java類上都增加JsonIgnoreProperties,萬一有時候忘記加了就麻煩了(這個是很可能會出現的),所以比較好的方法是在jackson包上增加一層封裝,然後對jackson進行統一的配置,針對上述情況的配置就是去使能DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,當然專案中還可以增加其他一些特殊的性質。封裝後就約定都使用封裝來呼叫jackson,這樣就會更加統一一些。