Jackson:将纪元反序列化为 LocalDate

kpa*_*r87 5 java json epoch jackson localdate

我有以下 JSON:

{
      "id" : "1",
      "birthday" : 401280850089
}
Run Code Online (Sandbox Code Playgroud)

和 POJO 类:

public class FbProfile {
    long id;
    @JsonDeserialize(using = LocalDateDeserializer.class)
    LocalDate birthday;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 Jackson 进行反序列化:

public FbProfile loadFbProfile(File file) throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    FbProfile profile = mapper.readValue(file, FbProfile.class);
    return profile;
}
Run Code Online (Sandbox Code Playgroud)

但它抛出一个异常:

com.fasterxml.jackson.databind.JsonMappingException:意外的令牌(VALUE_NUMBER_INT),预期的 VALUE_STRING:预期的数组或字符串。

我怎样才能反序列化纪元LocalDate?我想补充一点,如果我将数据类型从更改LocalDatejava.util.Date它,它工作得很好。因此,也许最好反序列化java.util.Date并创建 getter 和 setter 来进行 to/from 的转换LocalDate

kpa*_*r87 5

我设法编写了自己的解串器(感谢@Ole VV 将我指向Java 8 LocalDate Jackson 格式的帖子):

public class LocalDateTimeFromEpochDeserializer extends StdDeserializer<LocalDateTime> {

    private static final long serialVersionUID = 1L;

    protected LocalDateTimeFromEpochDeserializer() {
        super(LocalDate.class);
    }

    @Override
    public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        return Instant.ofEpochMilli(jp.readValueAs(Long.class)).atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

}
Run Code Online (Sandbox Code Playgroud)

关于时区的通知也非常有用。谢谢!

仍然悬而未决的问题是是否可以在不编写自己的反序列化器的情况下完成?

  • 这是一个猜测:我的猜测是,如果您坚持在“LocalDate”和自 Epoch 以来的毫秒之间进行序列化,您将需要自己的反序列化器。如果您可以用格式化的日期字符串 * 或 * 替换长毫秒,您会接受获取一个 `Instant` 而不是 `LocalDate`,我会更乐观地使用内置的反序列化。说几乎没有触及杰克逊的表面。很高兴你找到了一条路。 (2认同)