如何自定義Jackson序列化 @JsonSerialize
阿新 • • 發佈:2022-01-02
目錄
- 自定義Jackson序列化 @onSerialize
- jackson自定義全域性序列化、反序列化
- 建立序列化類
- 建立反序列化類
- 將兩個類註冊進入jackson核心物件objectMapper
- 小結一下
自定義Jackson序列化 @JsonSerialize
自定義json序列化需要實現StdSerializer<T>或者JsonSerializer<T>。
我要序列化House這個類,加上註解,指定用於序列化的類
package com.xhx.json.entity; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.xhx.json.serializers.HourseSerializer; import .util.Date; @JsonSerialize(using = HourseSerializer.class) public class Hourse { private String location; private Date buildDate; public String getLocation() { return location;} public void setLocation(String location) { this.location = location; } public Date getBuildDate() { return buildDate; } public void setBuildDate(Date buildDate) { this.buildDate = buildDate; } }
package com.xhx.json.serializers; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.xhx.json.entity.Hourse; import java.io.IOException; public class HourseSerializer extends StdSerializer<Hourse> { public HourseSerializer(){ super(Hourse.class); } protected HourseSerializer(Class<Hourse> t) { super(t); } @Override public void serialize(Hourse hourse,JsonGenerator generator,SerializerProvider provider) throws IOException { generator.writeStartObject(); generator.writeFieldName("id"); generator.writeString("自定義"); generator.writeFieldName("location"); generator.writeString(hourse.getLocation()); generator.writeObjectField("buildDate",hourse.getBuildDate()); generator.writeEndObject(); } }
測試:
jackson自定義全域性序列化、反序列化
需要自定義Jackson序列化和反序列化有兩種方式,一種是全域性定義,一種是非全域性定義。先來看看全域性定義。全域性定義的步驟如下,以定義一個localDateTime的序列化和反序列化為例:
建立序列化類
建立一個序列化類然後繼承JsonSerializer,重寫serialize序列化方法。其中第一個引數localDateTime為JsonSerializer的泛型,表示的是被序列化的型別的值,第二個引數jsonGenerator表示的是用於輸出生成的Json內容,第三個引數暫時沒明白什麼應用場景。重寫方法一般是將想要序列化的字串傳入 jsonGenerator.writeString。
public final class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer(); public LocalDateTimeSerializer() { } @Override public void serialize(LocalDateTime localDateTime,JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException,JsonProcessingException { jsonGenerator.writeString(DateUtil.format(localDateTime,DateUtil.DateTimeFormatEnum.DATE_TIME_FORMAT_4)); } }
建立反序列化類
建立兩個類,一個類繼承JsonDeserializer,一個類繼承KeyDeserializer,重寫deserialize反序列化方法。引數jsonParser用於讀取json內容的解析,deserializationContext可用於訪問此有關反序列化的上下文(暫時也不知道怎麼用),返回值則是JsonDeserializer的泛型物件,表示要反序列化的物件。一般用法是通過jsonParser.getText().trim()獲取該欄位json字串,然後將該字串轉換為物件返回。
public final class LocalTimeDeserializer extends JsonDeserializer<LocalTime> {
public static final LocalTimeDeserializer INSTANCE = new LocalTimeDeserializer();
public LocalTimeDeserializer() {
}
@Override
public LocalTime deserialize(JsonParser jsonParser,DeserializationContext deserializationContext) throws IOException,JsonProcessingException {
String text = jsonParser.getText().trim();
retuwww.cppcns.comrn LocalTime.parse(text,DateUtil.DATE_TIME_FORMATTER_6);
}
}
public final class LocalDateTimeKeyDeserializer extends KeyDeserializer {
public stathttp://www.cppcns.comic final LocalDateTimeKeyDeserializer INSTANCE = new LocalDateTimeKeyDeserializer();
public LocalDateTimeKeyDeserializer() {
}
@Override
public Object deserializeKey(String s,JsonProcessingException {
return StringUtils.isBlank(s) ? null : LocalDahttp://www.cppcns.comteTime.parse(s,DateUtil.DATE_TIME_FORMATTER_4);
}
}
將兩個類註冊進入jackson核心物件objectMapper
@Bean public ObjectMapper objectMapper(){ ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY); //不註釋,會導致swagger報錯 //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); //關閉日期序列化為時間戳的功能 objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); //關閉序列化的時候沒有為屬性找到getter方法,報錯 objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); //關閉反序列化的時候,沒有找到屬性的setter報錯 objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); //序列化的時候序列物件的所有屬性 objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); //反序列化的時候如果多了其他屬性,不丟擲異常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); //如果是空物件的時候,不拋異常 objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false); SimpleModule simpleModule = new SimpleModule(); //json值序列化 simpleModule.addSerializer(LocalDateTime.class,LocalDateTimeSerializer.INSTANCE); //json值反序列化 simpleModule.addDeserializer(LocalDateTime.class,LocalDateTimeDeserializer.INSTANCE); //json鍵序列化 simpleModule.addKeySerializer(LocalDateTime.class,LocalDateTimeSerializer.INSTANCE); //json鍵反序列化 simpleModule.addKeyDeserializer(LocalDateTime.class,LocalDateTimeKeyDeserializer.INSTANCE); objectMapper.registerModule(simpleModule); return objectMapper; }
小結一下
以上,通過objectMapper的配置,完成了全域性序列化、反序列化的配置,如果不需要全域性則通過@jsonserialize或 @JsonDeserialize指定使用的序列化、反序列化類。僅為個人經驗,希望能給大家一個參考,也希望大家多多支援我們