您好,登錄后才能下訂單哦!
如何自定義JsonSerialize以及Deserialize實現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
LocalDateTime
反序列化異常首先我們定義一個java POJO實體類,其中關(guān)鍵的成員變量時birthDate
,我們沒有采用Date數(shù)據(jù)類型,而是采用了Java8 新的日期類型LocalDateTime
,使用LocalDateTime
的好處我就不多說了,有很多的文章解釋說明。我們把精力放回到Jackson的JSON格式序列化與反序列化內(nèi)容上來。
[@Data](https://my.oschina.net/difrik) public class PlayerStar4 { private String name; //姓名 private LocalDateTime birthDate; //出生日期 }
下面的代碼,我們首先定義了一個PlayerStar4類的對象player,然后
使用writeValueAsString方法將player對象序列化為JSON字符串jsonString
然后使用readValue方法將JSON字符串jsonString ,反序列化為PlayerStar4類的對象
[@Test](https://my.oschina.net/azibug) void testJSON2Object() throws IOException { ObjectMapper mapper = new ObjectMapper(); PlayerStar4 player = new PlayerStar4(); player.setName("curry");//我并不知道庫里的生日,這里是編造的 player.setBirthDate(LocalDateTime.of(1986,4,5,12,50)); //將player對象以JSON格式進行序列化為String對象 String jsonString = mapper.writeValueAsString(player); System.out.println(jsonString); //將JSON字符串反序列化為java對象 PlayerStar4 curry = mapper.readValue(jsonString, PlayerStar4.class); System.out.println(curry); }
但是上面的代碼報錯了,從下圖中可以看出
將player對象序列化為JSON字符串jsonString 的過程被正常執(zhí)行了,但是LocalDateTime序列化之后的結(jié)果,是圖中”黃框中的黃框“內(nèi)容。
將JSON字符串反序列化的過程報錯了,因為Jackson默認(rèn)情況下,根本不認(rèn)識圖中”黃框中的黃框“內(nèi)容這種LocalDateTime序列化之后的JSON字符串?dāng)?shù)據(jù)結(jié)構(gòu)。無法把它反序列化為java對象。
怎么辦?我們需要自定義序列化及反序列化類型轉(zhuǎn)換器,有兩種方法
繼承StdConverter類,自定義實現(xiàn)String與LocalDateTime相互轉(zhuǎn)換
繼承JsonSerializer和JsonDeserializer類,自定義實現(xiàn)String與LocalDateTime相互轉(zhuǎn)換
繼承StdConverter類,將LocalDateTime序列化為String數(shù)據(jù)類型
public class LocalDateTimeToStringConverter extends StdConverter<LocalDateTime, String> { static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); @Override public String convert(LocalDateTime value) { return value.format(DATE_FORMATTER); } }
繼承StdConverter類,將String數(shù)據(jù)類型反序列化為LocalDateTime
public class StringToLocalDatetimeConverter extends StdConverter<String, LocalDateTime> { @Override public LocalDateTime convert(String value) { return LocalDateTime.parse(value, LocalDateTimeToStringConverter.DATE_FORMATTER); } }
自定義的轉(zhuǎn)換器完成之后,我們就可以在對應(yīng)的成員變量上,使用@JsonSerialize
指定序列化轉(zhuǎn)換器,@JsonDeserialize
指定反序列化轉(zhuǎn)換器。
@JsonSerialize(converter = LocalDateTimeToStringConverter.class) @JsonDeserialize(converter = StringToLocalDatetimeConverter.class) private LocalDateTime birthDate;
然后調(diào)用第一小節(jié)中的測試用例,就不會出現(xiàn)異常了??刂婆_打印輸出結(jié)果如下,第一行是序列化結(jié)果JSON格式字符串,第二行是Java 對象的toString()方法的打印結(jié)果。
{"name":"curry","birthDate":"1986-4-5 12:50:00"} PlayerStar4(name=curry, birthDate=1986-04-05T12:50)
繼承JsonSerializer<LocalDateTime>
類,將LocalDateTime序列化為String數(shù)據(jù)類型
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); @Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException { String s = value.format(DATE_FORMATTER); gen.writeString(s); } }
繼承JsonDeserializer<LocalDateTime>
類,將String數(shù)據(jù)類型反序列化為LocalDateTime
public class LocalDatetimeDeserializer extends JsonDeserializer<LocalDateTime> { @Override public LocalDateTime deserialize(JsonParser p, DeserializationContext ctx) throws IOException { String str = p.getText(); return LocalDateTime.parse(str, LocalDateTimeSerializer.DATE_FORMATTER); } }
對于相對小白的讀者,上面的自定義序列化及反序列化轉(zhuǎn)換過程你都沒懂,對于LocalDateTime的異常你也不要慌,Jackson已經(jīng)給出了解決方案。
需要特別和大家強調(diào)的是LocalDateTimeSerializer和LocalDateTimeDeserializer其實并不需要我們自己去定義,因為Jackson已經(jīng)幫我們定義好了。 之所以我還做了自定義的實現(xiàn)的介紹,是因為要為大家講解這個自定義序列化和反序列化類型轉(zhuǎn)換的實現(xiàn)過程,以后你再遇到其他的特殊的數(shù)據(jù)類型轉(zhuǎn)換,或者LocalDateTime類型的特殊日期格式等,都可以自己來定義JsonSerialize和JsonDeserialize來實現(xiàn)數(shù)據(jù)類型的轉(zhuǎn)換。
下面的這兩個類就是Jackson已經(jīng)幫我們定義好的LocalDateTimeSerializer和LocalDateTimeDeserializer。
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
使用方法是在對應(yīng)的成員變量上,使用@JsonSerialize
指定序列化轉(zhuǎn)換器,@JsonDeserialize
指定反序列化轉(zhuǎn)換器。
@JsonSerialize(using = LocalDateTimeSerializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class) private LocalDateTime birthDate;
執(zhí)行之后的序列化和反序列化結(jié)果,和方法一、方法二自定義的實現(xiàn)效果是一樣的。
看完上述內(nèi)容,你們掌握如何自定義JsonSerialize以及Deserialize實現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。