欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的Jackson自定義序列化詳解

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

Jackson自定義序列化

本篇簡(jiǎn)單寫寫Jackson中自定義序列化的方式。

假設(shè)有類Country和Leader,分別表示國(guó)家以及國(guó)家領(lǐng)導(dǎo)人,領(lǐng)導(dǎo)人除了姓名外還有年齡和民族,定義如下

@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;
}

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

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

輸出結(jié)果

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

可以看到,正常的序列化方式會(huì)將leader的屬性都進(jìn)行序列化。

然而,有些時(shí)候,我們并不需要關(guān)心這個(gè)國(guó)家的領(lǐng)導(dǎo)人的詳細(xì)信息,我們只需要知道他叫什么名字即可,例如我們想在序列化之后輸入如下的JSON,那就需要定制序列化方式。

1、自定義序列化器

首先定義一個(gè)序列化器,繼承自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;
        }
        // 直接輸入領(lǐng)導(dǎo)人姓名,不需要起始和結(jié)束的花括號(hào)
        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ù)庫(kù)或通過(guò)其他操作返回leader詳細(xì)信息
        if ("忽必烈".equals(leaderName)) {
            Leader leader = new Leader();
            leader.setLeaderName(leaderName);
            leader.setAge(79);
            leader.setNation("蒙古族");
            return leader;
        }
        return null;
    }
}

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

注意,不能添加在Leader類上,否則會(huì)改變Leader類的默認(rèn)序列化和反序列化方式,這里序列化的目標(biāo)依舊是Country

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

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

測(cè)試

@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));
}

輸出結(jié)果

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

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

再來(lái)測(cè)試反序列化

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

輸出結(jié)果

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

可以看到,結(jié)果也是正常的。

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ù)庫(kù)或通過(guò)其他操作返回leader詳細(xì)信息
        if ("忽必烈".equals(leaderName)) {
            Leader leader = new Leader();
            leader.setLeaderName(leaderName);
            leader.setAge(79);
            leader.setNation("蒙古族");
            return leader;
        }
        return null;
    }

}

注意:@JsonCreator注解所標(biāo)注的類必須要是static的

再來(lái)執(zhí)行上面的測(cè)試類test6(),輸出結(jié)果如下

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

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

@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]

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

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

相關(guān)文章

  • Java實(shí)現(xiàn)狀態(tài)模式的示例代碼

    Java實(shí)現(xiàn)狀態(tài)模式的示例代碼

    狀態(tài)模式是一種行為型設(shè)計(jì)模式,允許對(duì)象根據(jù)其內(nèi)部狀態(tài)改變行為,本文主要介紹了Java實(shí)現(xiàn)狀態(tài)模式的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • Vue3實(shí)現(xiàn)多頁(yè)面跳轉(zhuǎn)效果的幾種方式

    Vue3實(shí)現(xiàn)多頁(yè)面跳轉(zhuǎn)效果的幾種方式

    Vue.js是一個(gè)用于構(gòu)建用戶界面的漸進(jìn)式 JavaScript 框架,它提供了多種方法來(lái)實(shí)現(xiàn)頁(yè)面之間的導(dǎo)航,在 Vue 3 中,頁(yè)面跳轉(zhuǎn)主要通過(guò) Vue Router 來(lái)管理,同時(shí)也支持其他方式如編程式導(dǎo)航和使用錨點(diǎn)鏈接,本文將詳細(xì)介紹 Vue 3 中的各種頁(yè)面跳轉(zhuǎn)方式,需要的朋友可以參考下
    2025-03-03
  • springboot+mybatis快速插入大量數(shù)據(jù)的具體實(shí)現(xiàn)

    springboot+mybatis快速插入大量數(shù)據(jù)的具體實(shí)現(xiàn)

    最近導(dǎo)入表格數(shù)據(jù)時(shí)需要同時(shí)插入修改大量數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于springboot+mybatis快速插入大量數(shù)據(jù)的具體實(shí)現(xiàn),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • Springboot通過(guò)谷歌Kaptcha?組件生成圖形驗(yàn)證碼功能

    Springboot通過(guò)谷歌Kaptcha?組件生成圖形驗(yàn)證碼功能

    Kaptcha是谷歌開(kāi)源的一款簡(jiǎn)單實(shí)用的圖形驗(yàn)證碼組件。我個(gè)人推薦它的最大原因是容易上手,采用約定大于配置的方式,快速契合到項(xiàng)目中,這篇文章主要介紹了Springboot通過(guò)谷歌Kaptcha組件生成圖形驗(yàn)證碼的方法,需要的朋友可以參考下
    2023-05-05
  • SpringCloud中NacosNamingService的作用詳解

    SpringCloud中NacosNamingService的作用詳解

    這篇文章主要介紹了SpringCloud中NacosNamingService的作用詳解,NacosNamingService類完成服務(wù)實(shí)例注冊(cè),撤銷與獲取服務(wù)實(shí)例操作,NacosNamingService初始化采用單例模式,使用反射生成,需要的朋友可以參考下
    2023-11-11
  • Java實(shí)現(xiàn)計(jì)算機(jī)程序設(shè)計(jì)思路

    Java實(shí)現(xiàn)計(jì)算機(jī)程序設(shè)計(jì)思路

    這篇文章主要為大家介紹了Java實(shí)現(xiàn)計(jì)算機(jī)程序設(shè)計(jì)思路,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • java使用CollectionUtils工具類判斷集合是否為空方式

    java使用CollectionUtils工具類判斷集合是否為空方式

    這篇文章主要介紹了java使用CollectionUtils工具類判斷集合是否為空方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java?long?類型數(shù)據(jù)的賦值方式

    java?long?類型數(shù)據(jù)的賦值方式

    這篇文章主要介紹了java?long?類型數(shù)據(jù)的賦值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 淺談java Collection中的排序問(wèn)題

    淺談java Collection中的排序問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談java Collection中的排序問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • Springboot中使用緩存的示例代碼

    Springboot中使用緩存的示例代碼

    這篇文章主要介紹了Springboot中使用緩存的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論