最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中Jackson的多態(tài)反序列化詳解

 更新時(shí)間:2023年11月06日 10:32:59   作者:楊某人信了你的邪  
這篇文章主要介紹了Java中Jackson的多態(tài)反序列化詳解,多態(tài)序列化與反序列化,主要是借助于Jackson的@JsonTypeInfo與@JsonSubTypes注解實(shí)現(xiàn),下面將通過幾個(gè)例子來(lái)簡(jiǎn)述其運(yùn)用,需要的朋友可以參考下

Jackson多態(tài)反序列化

多態(tài)序列化與反序列化,主要是借助于Jackson的@JsonTypeInfo與@JsonSubTypes注解實(shí)現(xiàn),下面將通過幾個(gè)例子來(lái)簡(jiǎn)述其運(yùn)用。

首先,創(chuàng)建幾個(gè)基本的實(shí)體類。這些類都比較簡(jiǎn)單,有共同的屬性也有不同的屬性,這里為了簡(jiǎn)單,共同屬性就只有一個(gè)type。

@Data
public class Person {
    protected Integer type;
}
@EqualsAndHashCode(callSuper = true)
@Data
public class Student extends Person {
    private String studentName;
}
@EqualsAndHashCode(callSuper = true)
@Data
public class Teacher extends Person {
    private String teacherName;
}
@EqualsAndHashCode(callSuper = true)
@Data
public class Doctor extends Person{
    private String doctorName;
}

1、通過類型判斷

在父類上加如下注解。因?yàn)槭峭ㄟ^類型進(jìn)行序列化,所以只需要加一個(gè)注解就夠了。

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
@Data
public class Person {
    protected Integer type;
}

測(cè)試

@Test
void test1() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    Student student = new Student();
    student.setType(0);
    student.setStudentName("三好學(xué)生~");
    System.out.println(objectMapper.writeValueAsString(student));
    String json1 = "{\"@class\":\"com.example.jackson.Student\",\"studentName\":\"三好學(xué)生~\",\"type\":null}";
    String json2 = "{\"@class\":\"com.example.jackson.Teacher\",\"teacherName\":\"十佳教師~\",\"type\":null}";
    System.out.println(objectMapper.readValue(json1, Person.class));
    System.out.println(objectMapper.readValue(json2, Person.class));
}

輸出

{"@class":"com.example.jackson.Student","type":0,"studentName":"三好學(xué)生~"}
Student(studentName=三好學(xué)生~)
Teacher(teacherName=十佳教師~)

如果不想用@class做為類型標(biāo)識(shí),也可使用簡(jiǎn)略模式

@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)
@Data
public class Person {
    protected Integer type;
}

測(cè)試

@Test
void test2() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    Student student = new Student();
    student.setType(0);
    student.setStudentName("三好學(xué)生~");
    System.out.println(objectMapper.writeValueAsString(student));
    String json1 = "{\"@c\":\".Student\",\"studentName\":\"三好學(xué)生~\",\"type\":null}";
    String json2 = "{\"@c\":\".Teacher\",\"teacherName\":\"十佳教師~\",\"type\":null}";
    System.out.println(objectMapper.readValue(json1, Person.class));
    System.out.println(objectMapper.readValue(json2, Person.class));
}

輸出

{"@c":".Student","type":0,"studentName":"三好學(xué)生~"}
Student(studentName=三好學(xué)生~)
Teacher(teacherName=十佳教師~)

2、通過屬性值判斷

上面的實(shí)體類中,存在共同屬性,比如type就是一個(gè)共同屬性,可以通過這個(gè)共同屬性的值來(lái)判斷需要反序列化為哪一個(gè)類。

如下,當(dāng)選擇屬性為type,當(dāng)值為1時(shí)反序列化為Student,值為2時(shí)反序列化為Teacher,值為3或4則反序列化為Doctor。

因?yàn)閠ype是類中已存在的屬性,所以@JsonTypeInfo注解中的include屬性設(shè)置為EXISTING_PROPERTY,否則序列化的時(shí)候不管原先類中有沒有type屬性,都會(huì)在序列化后的json中添加一個(gè)type,出現(xiàn)一個(gè)json中有兩個(gè)相同屬性的情況,這里就不貼出來(lái)了,感興趣可以自己去試一下。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "type", visible = true)
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value = Student.class, name = "1"),
        @JsonSubTypes.Type(value = Teacher.class, name = "2"),
        @JsonSubTypes.Type(value = Doctor.class, names = {"3", "4"})
})
@Data
public class Person {
    protected Integer type;
}

測(cè)試

@Test
void test3() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    Student student = new Student();
    student.setType(1);
    student.setStudentName("三好學(xué)生~");
    System.out.println(objectMapper.writeValueAsString(student));
    String json1 = "{\"studentName\":\"三好學(xué)生~\",\"type\":1}";
    String json2 = "{\"teacherName\":\"十佳教師~\",\"type\":2}";
    String json3 = "{\"doctorName\":\"華佗在世~\",\"type\":4}";
    System.out.println(objectMapper.readValue(json1, Person.class));
    System.out.println(objectMapper.readValue(json2, Person.class));
    System.out.println(objectMapper.readValue(json3, Person.class));
}

輸出

{"type":1,"studentName":"三好學(xué)生~"}
Student(studentName=三好學(xué)生~)
Teacher(teacherName=十佳教師~)
Doctor(doctorName=華佗在世~)

只不過使用這種方法有弊端,首先就是需要將涉及到反序列化的所有子類都標(biāo)注到基類上便于基類感知,如果子類多了,那就顯得臃腫,而且也違反了開閉原則。所以介紹下面的另一種方式

通過屬性值判斷,除了上面的使用@JsonSubTypes在基類上全都列出來(lái)之外,還可以使用@JsonTypeName注解標(biāo)注在子類上,如下

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "type", visible = true)
@Data
public class Person {
    protected Integer type;
}
@EqualsAndHashCode(callSuper = true)
@Data
@JsonTypeName("1")
public class Student extends Person {
    private String studentName;
}

其他幾個(gè)類也是一樣,就不貼出來(lái)了。

測(cè)試

@Test
void test4() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();

    // 關(guān)鍵的是這行
    objectMapper.registerSubtypes(Student.class, Teacher.class, Doctor.class);

    Student student = new Student();
    student.setType(1);
    student.setStudentName("三好學(xué)生~");
    System.out.println(objectMapper.writeValueAsString(student));
    String json1 = "{\"studentName\":\"三好學(xué)生~\",\"type\":1}";
    String json2 = "{\"teacherName\":\"十佳教師~\",\"type\":2}";
    String json3 = "{\"doctorName\":\"華佗在世~\",\"type\":3}";
    System.out.println(objectMapper.readValue(json1, Person.class));
    System.out.println(objectMapper.readValue(json2, Person.class));
    System.out.println(objectMapper.readValue(json3, Person.class));
}

輸出

Student(studentName=三好學(xué)生~)
Teacher(teacherName=十佳教師~)
Doctor(doctorName=華佗在世~)

通過ObjectMapper的registerSubtypes方法注冊(cè)子類,這樣一來(lái)就不需要在基類上標(biāo)注@JsonSubTypes注解了。

當(dāng)然,除了使用@JsonTypeName注解,然后直接注冊(cè)這個(gè)類之外,還可以通過下面的方式進(jìn)行注冊(cè),效果是一樣的

objectMapper.registerSubtypes(new NamedType(Student.class, "1"));

上面的代碼是演示,所以在注冊(cè)時(shí)是一個(gè)個(gè)寫死的,但實(shí)際上,不可能將所有類全都寫出來(lái)進(jìn)行注冊(cè),實(shí)際上可以借助一些工具進(jìn)行來(lái)獲取所有的子類,比如Reflections

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.10.2</version>
</dependency>
// 獲取該路徑下所有類
Reflections reflections = new Reflections("com.example");
// 獲取對(duì)應(yīng)類的所有子類
Set<Class<? extends Person>> classSet = reflections.getSubTypesOf(Person.class);
for (Class<? extends Person> clazz : classSet) {
    // 將帶有@JsonTypeName注解的類進(jìn)行注冊(cè)
    if (clazz.isAnnotationPresent(JsonTypeName.class)) {
        objectMapper.registerSubtypes(clazz);
    }
}

到此這篇關(guān)于Java中Jackson的多態(tài)反序列化詳解的文章就介紹到這了,更多相關(guān)Jackson多態(tài)反序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解@ConfigurationProperties實(shí)現(xiàn)原理與實(shí)戰(zhàn)

    詳解@ConfigurationProperties實(shí)現(xiàn)原理與實(shí)戰(zhàn)

    這篇文章主要介紹了詳解@ConfigurationProperties實(shí)現(xiàn)原理與實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • MyBatis實(shí)現(xiàn)三級(jí)樹查詢的示例代碼

    MyBatis實(shí)現(xiàn)三級(jí)樹查詢的示例代碼

    在實(shí)際項(xiàng)目開發(fā)中,樹形結(jié)構(gòu)的數(shù)據(jù)查詢是一個(gè)非常常見的需求,比如組織架構(gòu)、菜單管理、地區(qū)選擇等場(chǎng)景都需要處理樹形數(shù)據(jù),本文將詳細(xì)講解如何使用MyBatis實(shí)現(xiàn)三級(jí)樹形數(shù)據(jù)的查詢,需要的朋友可以參考下
    2024-12-12
  • Mybatis使用簡(jiǎn)述及環(huán)境搭建

    Mybatis使用簡(jiǎn)述及環(huán)境搭建

    MyBatis是一款優(yōu)秀的Java持久層框架,它通過XML或注解的方式將 Java對(duì)象與數(shù)據(jù)庫(kù)中的記錄進(jìn)行映射,本文給大家介紹Mybatis使用簡(jiǎn)述,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Spring響應(yīng)式編程之Reactor操作符詳解

    Spring響應(yīng)式編程之Reactor操作符詳解

    文章介紹了Reactor庫(kù)中常用的響應(yīng)式流操作符,分為創(chuàng)建、轉(zhuǎn)換、組合、條件和錯(cuò)誤處理五類,詳細(xì)列舉了每類操作符的功能和用途,這些操作符旨在提高響應(yīng)式流的可讀性和開發(fā)效率,幫助開發(fā)者更高效地處理數(shù)據(jù)流
    2025-09-09
  • 使用多個(gè)servlet時(shí)Spring security需要指明路由匹配策略問題

    使用多個(gè)servlet時(shí)Spring security需要指明路由匹配策略問題

    這篇文章主要介紹了使用多個(gè)servlet時(shí)Spring security需要指明路由匹配策略問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java關(guān)于Date日期類型的大小比較

    java關(guān)于Date日期類型的大小比較

    這篇文章主要介紹了java關(guān)于Date日期類型的大小比較,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot v2.2以上重復(fù)讀取Request Body內(nèi)容的解決方案

    SpringBoot v2.2以上重復(fù)讀取Request Body內(nèi)容的解決方案

    這篇文章主要介紹了SpringBoot v2.2以上重復(fù)讀取Request Body內(nèi)容的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java Swing組件布局管理器之FlowLayout(流式布局)入門教程

    Java Swing組件布局管理器之FlowLayout(流式布局)入門教程

    這篇文章主要介紹了Java Swing組件布局管理器之FlowLayout(流式布局),結(jié)合實(shí)例形式分析了Swing組件布局管理器FlowLayout流式布局的常用方法及相關(guān)使用技巧,需要的朋友可以參考下
    2017-11-11
  • java利用反射實(shí)現(xiàn)動(dòng)態(tài)代理示例

    java利用反射實(shí)現(xiàn)動(dòng)態(tài)代理示例

    這篇文章主要介紹了java利用反射實(shí)現(xiàn)動(dòng)態(tài)代理示例,需要的朋友可以參考下
    2014-04-04
  • Java中HashMap和HashSet的高效使用技巧分享

    Java中HashMap和HashSet的高效使用技巧分享

    這篇文章主要為大家詳細(xì)介紹了Java中HashMap和HashSet的高效使用技巧,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03

最新評(píng)論

连城县| 惠东县| 龙岩市| 稻城县| 乾安县| 台前县| 花莲县| 扬中市| 襄城县| 盐城市| 武宁县| 赤壁市| 旺苍县| 竹北市| 鄂尔多斯市| 阳东县| 灵川县| 于都县| 福州市| 南通市| 上虞市| 三都| 阳城县| 堆龙德庆县| 阳朔县| 杭锦旗| 庆城县| 隆昌县| 万荣县| 奇台县| 白城市| 武冈市| 东乡县| 阿拉善左旗| 乌拉特前旗| 新龙县| 邹平县| 龙江县| 韶山市| 呼伦贝尔市| 德昌县|