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

Java的Jackson自定義序列化詳解

 更新時間:2023年11月06日 10:17:25   作者:楊某人信了你的邪  
這篇文章主要介紹了Java的Jackson自定義序列化詳解,對比序列化器,可以看到,使用@JsonValue注解已經(jīng)將Leader類的序列化方式改變了,進而影響了Country類,再來執(zhí)行test7()測試反序列化,結果與之前是一致的,需要的朋友可以參考下

Jackson自定義序列化

本篇簡單寫寫Jackson中自定義序列化的方式。

假設有類Country和Leader,分別表示國家以及國家領導人,領導人除了姓名外還有年齡和民族,定義如下

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Country {
    private String countryName;
    private Leader leader;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Leader {
    private String leaderName;
    private Integer age;
    private String nation;
}

基于上述定義,且看下面的代碼輸出結果結果

@Test
void test5() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    Country country = new Country("元朝", new Leader("忽必烈", 79, "蒙古族"));
    System.out.println(objectMapper.writeValueAsString(country));
}

輸出結果

{"countryName":"元朝","leader":{"leaderName":"忽必烈","age":79,"nation":"蒙古族"}}

可以看到,正常的序列化方式會將leader的屬性都進行序列化。

然而,有些時候,我們并不需要關心這個國家的領導人的詳細信息,我們只需要知道他叫什么名字即可,例如我們想在序列化之后輸入如下的JSON,那就需要定制序列化方式。

1、自定義序列化器

首先定義一個序列化器,繼承自Serializer類或其子類

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;

public class LeaderSerializer extends StdSerializer<Leader> {
    public LeaderSerializer() {
        this(null);
    }

    protected LeaderSerializer(Class<Leader> t) {
        super(t);
    }

    @Override
    public void serialize(Leader value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }
        // 直接輸入領導人姓名,不需要起始和結束的花括號
        gen.writeString(value.getLeaderName());
    }
}

有了序列化,自然需要反序列化

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;

public class LeaderDeserializer extends StdDeserializer<Leader> {
    public LeaderDeserializer() {
        this(null);
    }

    protected LeaderDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Leader deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String leaderName = p.getValueAsString();
        if (leaderName == null) {
            return null;
        }
        return getLeaderByName(leaderName);
    }

    private Leader getLeaderByName(String leaderName) {
        // TODO 查詢數(shù)據(jù)庫或通過其他操作返回leader詳細信息
        if ("忽必烈".equals(leaderName)) {
            Leader leader = new Leader();
            leader.setLeaderName(leaderName);
            leader.setAge(79);
            leader.setNation("蒙古族");
            return leader;
        }
        return null;
    }
}

然后應用序列化類,在leader屬性上添加序列化和反序列化注解。

注意,不能添加在Leader類上,否則會改變Leader類的默認序列化和反序列化方式,這里序列化的目標依舊是Country

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Country {
    private String countryName;

    @JsonSerialize(using = LeaderSerializer.class)
    @JsonDeserialize(using = LeaderDeserializer.class)
    private Leader leader;
}

測試

@Test
void test6() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    Leader leader = new Leader("忽必烈", 79, "蒙古族");
    Country country = new Country("元朝", leader);
    System.out.println(objectMapper.writeValueAsString(leader));
    System.out.println(objectMapper.writeValueAsString(country));
}

輸出結果

{"leaderName":"忽必烈","age":79,"nation":"蒙古族"}
{"countryName":"元朝","leader":"忽必烈"}

從輸出結果可以看到,Leader的序列化方式依舊是正常的,但是Country中的leader屬性序列化后輸出的只有l(wèi)eaderName屬性,已經(jīng)實現(xiàn)了我們需要的功能。

再來測試反序列化

@Test
void test7() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    String json = "{\"countryName\":\"元朝\",\"leader\":\"忽必烈\"}";
    System.out.println(objectMapper.readValue(json, Country.class));
}

輸出結果

Country(countryName=元朝, leader=Leader(leaderName=忽必烈, age=79, nation=蒙古族))

可以看到,結果也是正常的。

2、使用@JsonValue和@JsonCreator注解

首先將上面Country中l(wèi)eader屬性上加的序列化注解和反序列化注解去掉,還原為最初,然后修改Leader類如下

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Leader {

    @JsonValue
    private String leaderName;

    private Integer age;
    private String nation;

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static Leader getLeaderByName(String leaderName) {
        // TODO 查詢數(shù)據(jù)庫或通過其他操作返回leader詳細信息
        if ("忽必烈".equals(leaderName)) {
            Leader leader = new Leader();
            leader.setLeaderName(leaderName);
            leader.setAge(79);
            leader.setNation("蒙古族");
            return leader;
        }
        return null;
    }

}

注意:@JsonCreator注解所標注的類必須要是static的

再來執(zhí)行上面的測試類test6(),輸出結果如下

"忽必烈"
{"countryName":"元朝","leader":"忽必烈"}

對比序列化器,可以看到,使用@JsonValue注解已經(jīng)將Leader類的序列化方式改變了,進而影響了Country類。再來執(zhí)行test7()測試反序列化,結果與之前是一致的。但是執(zhí)行下面的反序列化測試的時候卻報了錯,從報錯信息可以看到是JSON識別錯誤,暫時還未找到解決方法,待后續(xù)補充完善。

@Test
void test8() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    System.out.println(objectMapper.readValue("忽必烈", Leader.class));
}
com.fasterxml.jackson.core.JsonParseException: Unrecognized token '忽必烈': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
 at [Source: (String)"忽必烈"; line: 1, column: 4]

所以更推薦使用自定義序列化器和反序列化器的方式來實現(xiàn)。

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

相關文章

  • Java中BigDecimal精度和相等比較的坑

    Java中BigDecimal精度和相等比較的坑

    BigDecimal是一種精確的數(shù)字類,一般用于高精度的開發(fā)領域中,例如銀行。下面這篇文章主要給大家介紹了關于Java中BigDecimal精度和相等比較的坑的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-09-09
  • JAVA中string數(shù)據(jù)類型轉換詳解

    JAVA中string數(shù)據(jù)類型轉換詳解

    在JAVA中string是final類,提供字符串不可以修改,string類型在項目中經(jīng)常使用,下面給大家介紹了string七種數(shù)據(jù)類型轉換,需要的朋友可以參考下
    2015-07-07
  • Spring Boot集成BCryptPasswordEncoder實現(xiàn)密碼加密與驗證的實現(xiàn)方案

    Spring Boot集成BCryptPasswordEncoder實現(xiàn)密碼加密與驗證的實現(xiàn)方案

    文章介紹了如何在SpringBoot中集成BCryptPasswordEncoder實現(xiàn)密碼的加密和驗證,包括添加依賴、配置BCryptPasswordEncoder、在用戶注冊和登錄時使用BCryptPasswordEncoder進行密碼處理,以及注意事項,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • SpringBoot Shiro 權限注解不起作用的解決方法

    SpringBoot Shiro 權限注解不起作用的解決方法

    本文主要介紹了SpringBoot Shiro 權限注解不起作用的解決方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 如何用注解的方式實現(xiàn)Mybatis插入數(shù)據(jù)時返回自增的主鍵Id

    如何用注解的方式實現(xiàn)Mybatis插入數(shù)據(jù)時返回自增的主鍵Id

    這篇文章主要介紹了如何用注解的方式實現(xiàn)Mybatis插入數(shù)據(jù)時返回自增的主鍵Id,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Java elasticSearch-api的具體操作步驟講解

    Java elasticSearch-api的具體操作步驟講解

    這篇文章主要介紹了elasticSearch-api的具體操作步驟講解,本文通過詳細的步驟介紹和圖文代碼展示講解了該項技術,需要的朋友可以參考下
    2021-06-06
  • Java synchronized同步方法詳解

    Java synchronized同步方法詳解

    這篇文章主要為大家詳細介紹了Java synchronized同步方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 基于Spring Validation實現(xiàn)全局參數(shù)校驗異常處理的示例詳解

    基于Spring Validation實現(xiàn)全局參數(shù)校驗異常處理的示例詳解

    在 Spring Boot 項目開發(fā)中,接口參數(shù)校驗是保障數(shù)據(jù)合法性的關鍵環(huán)節(jié),Spring Validation 提供了便捷的參數(shù)校驗能力,下面我們就來看看具體的實現(xiàn)方法吧
    2025-08-08
  • Mac電腦安裝多個JDK版本的詳細圖文教程

    Mac電腦安裝多個JDK版本的詳細圖文教程

    目前使用的主流版本還是JDK 8,但偶爾會想體驗下新版本(或者舊版本),如果能裝多個版本的JDK,而且很方便的切換就好了,這篇文章主要給大家介紹了關于Mac電腦安裝多個JDK版本的相關資料,需要的朋友可以參考下
    2024-03-03
  • 關于Feign調(diào)用服務Headers傳參問題

    關于Feign調(diào)用服務Headers傳參問題

    這篇文章主要介紹了關于Feign調(diào)用服務Headers傳參問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評論

吉安县| 资阳市| 壶关县| 宁远县| 东光县| 阳曲县| 肃南| 大宁县| 东丽区| 垣曲县| 山东| 彰化县| 恭城| 石首市| 西青区| 高州市| 道孚县| 镇原县| 怀安县| 平阴县| 黄平县| 晋州市| 安仁县| 临洮县| 永丰县| 天祝| 登封市| 景宁| 柞水县| 沧州市| 文成县| 弋阳县| 布拖县| 莱州市| 普兰县| 铁岭市| 商洛市| 堆龙德庆县| 金华市| 习水县| 阳谷县|