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

时间:2019-02-17 14:57:45

标签: java json jackson

我正在开发一个存储事件发生日期的应用程序。我正在使用render()代表这一天,并将其作为字符串保存(例如java.time.DayOfWeekMONDAY)。

Jackson将此类型序列化为字符串,因此JSON表示形式看起来像存储在数据库中的值。但是,我想将其序列化/反序列化为数值。

我尝试使用WEDNESDAY,但是可用的数字形状基于索引,这是不希望的,因为@JsonFormat的值为MONDAY,而不是1

编写自定义序列化程序似乎是这里的唯一解决方案,但是我觉得这个问题已经以某种方式解决了。

2 个答案:

答案 0 :(得分: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进行移位的原因。

答案 1 :(得分:0)

为避免在应用程序的各层和各部分之间产生任何误解,最好是使用String表示形式:MONDAYWEDNESDAY等。如果要对此enum进行序列化与int一样,任何数字都可以并且一样好。无论如何,您都需要保留1MONDAY的信息。无论是01还是10都没有关系。在Java中,Calendar.MONDAY等于2DayOfWeek.MONDAY等于1,还有WeekFields.ISO,其中MONDAY是第一天和WeekFields.SUNDAY_START,其中SUNDAY是一周的第一天。

如果需要将1的{​​{1}}定义为所有MONDAY类的基本概念,则需要注册自定义序列化程序。自定义序列化器可能如下所示:

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

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

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
}

上面的代码显示:

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