1. 程式人生 > 程式設計 >如何自定義Jackson序列化 @JsonSerialize

如何自定義Jackson序列化 @JsonSerialize

目錄
  • 自定義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序列化@JsonSerialize

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指定使用的序列化、反序列化類。僅為個人經驗,希望能給大家一個參考,也希望大家多多支援我們