簡體   English   中英

如何使用Jackson正確地序列化/反序列化java.time.DayOfWeek?

[英]How to properly serialize/deserialize java.time.DayOfWeek with Jackson?

我正在開發一個存儲事件發生日期的應用程序。 我正在使用java.time.DayOfWeek表示這一天,並將其持久化為字符串(例如MONDAYWEDNESDAY )。

Jackson將這種類型序列化為字符串,因此JSON表示形式看起來像存儲在數據庫中的值。 但是,我想將其序列化/反序列化為數值。

我嘗試使用@JsonFormat ,但是可用的數字形狀基於索引,這是不希望的,因為MONDAY值為1 ,而不是0

編寫自定義序列化器似乎是這里唯一的解決方案,但是我覺得這個問題已經以某種方式解決了。

您可以忽略默認的getter並添加映射到DayOfWeek字段的其他方法。 對於設置器,您可以創建一個附加int而不是枚舉的設置器。

這是一個示例實現:

class MyDate {

    private DayOfWeek dow = DayOfWeek.MONDAY;// DayOfWeek.of(LocalDate.now().getDayOfWeek());

    @JsonIgnore
    public DayOfWeek getDow() {
        return dow;
    }

    public void setDow(int dow) {
        this.dow = DayOfWeek.of(dow + 1);
    }

    @JsonProperty("dow")
    public int getDayOfWeekNumber() {
        return dow.getValue() - 1; //0 for Monday
    }

    public void setDow(DayOfWeek dow) {
        this.dow = dow;
    }

    @Override
    public String toString() {
        return "[dow=" + dow + "]";
    }

    public static void main(String[] args) throws Exception {
        System.out.println(new ObjectMapper().writeValueAsString(new MyDate()));
        System.out.println(new ObjectMapper().readValue("{\"dow\":7}", MyDate.class));
    }
}

DayOfWeek不支持自定義一周的第一天或其索引。 這就是上面的代碼使用+/- 1進行移位的原因。

為了避免在應用程序的各層和各部分之間產生任何誤解,最好是使用String表示形式: MONDAYWEDNESDAY等。如果要將此enum序列化為int任何數字都可以並且一樣好。 在每一層上,您都必須保留1表示MONDAY的信息。 無論這將是0110也沒關系。 Java中, Calendar.MONDAY等於2DayOfWeek.MONDAY等於1 ,還有WeekFields.ISO ,其中MONDAY是第一天,而WeekFields.SUNDAY_START ,其中SUNDAY是一周的第一天。

如果您需要為MONDAY定義1作為所有POJO類的基本概念,則需要注冊自定義序列化程序。 自定義序列化器可能如下所示:

class DayOfWeekSerializer extends StdSerializer<DayOfWeek> {

    public DayOfWeekSerializer() {
        super(DayOfWeek.class);
    }

    @Override
    public void serialize(DayOfWeek value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeNumber(value.getValue());
    }
}

自定義解串器:

class DayOfWeekDeserializer extends StdDeserializer<DayOfWeek> {

    public DayOfWeekDeserializer() {
        super(DayOfWeek.class);
    }

    @Override
    public DayOfWeek deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return DayOfWeek.of(p.getIntValue());
    }
}

您可以像下面這樣注冊:

ObjectMapper createObjectMapper() {
    SimpleModule dayOfWeeModule = new SimpleModule("DayOfWeek module");
    dayOfWeeModule.addSerializer(DayOfWeek.class, new DayOfWeekSerializer());
    dayOfWeeModule.addDeserializer(DayOfWeek.class, new DayOfWeekDeserializer());

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(dayOfWeeModule);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);

    return mapper;
}

對於以下測試POJO class

class Days {

    private DayOfWeek monday = DayOfWeek.MONDAY;
    private DayOfWeek tuesday = DayOfWeek.TUESDAY;
    private DayOfWeek wednesday = DayOfWeek.WEDNESDAY;
    private DayOfWeek thursday = DayOfWeek.THURSDAY;
    private DayOfWeek friday = DayOfWeek.FRIDAY;
    private DayOfWeek saturday = DayOfWeek.SATURDAY;
    private DayOfWeek sunday = DayOfWeek.SUNDAY;

    // getter, setters, toString
}

用法示例:ObjectMapper mapper = createObjectMapper();

String json = mapper.writeValueAsString(new Days());
System.out.println(json);
System.out.println(mapper.readValue(json, Days.class));

上面的代碼打印:

{
  "monday" : 1,
  "tuesday" : 2,
  "wednesday" : 3,
  "thursday" : 4,
  "friday" : 5,
  "saturday" : 6,
  "sunday" : 7
}
Days{monday=MONDAY, tuesday=TUESDAY, wednesday=WEDNESDAY, thursday=THURSDAY, friday=FRIDAY, saturday=SATURDAY, sunday=SUNDAY}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM