java - Java 8 时间 API 的 ObjectMapper 配置

标签 java jackson java-time jackson-databind jackson-modules

我们正在从 Joda 迁移到 Java Time。目前我们在实体中使用 Joda 的 DateTime。 AFAIK DateTime 相当于 Java 中的两种类型:OffsetDateTimeZonedDateTime。由于我们要将它们持久保存在数据库中,因此我们将使用 OffsetDateTime(对此有何评论?)。

现在的问题是如何正确配置 Jackson 的 ObjectMapper。 我在网上找到的所有示例都是关于 Jackson 已经为其提供反序列化器实现的本地类型(例如 LocalDateTimeLocalDateTimeSerializerLocalDateTimeDeserializer)。

我终于设法做了这样的事情:

public class OffsetDateTimeSerializer extends StdSerializer<OffsetDateTime> {

    private final DateTimeFormatter formatter; // We need custom format!

    public OffsetDateTimeSerializer(DateTimeFormatter formatter) {
        super(OffsetDateTime.class);
        this.formatter = formatter;
    }

    @Override
    public void serialize(OffsetDateTime value, JsonGenerator generator, SerializerProvider provider) throws IOException {
        generator.writeString(value.format(formatter));
    }

}

public class OffsetDateTimeDeserializer extends StdDeserializer<OffsetDateTime> {

    private final DateTimeFormatter formatter; // We need custom format!

    public OffsetDateTimeDeserializer(DateTimeFormatter formatter) {
        super(OffsetDateTime.class);
        this.formatter = formatter;
    }

    @Override
    public OffsetDateTime deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
        return OffsetDateTime.parse(parser.readValueAs(String.class), formatter);
    }

}

现在我的问题是配置 Jackson 的 ObjectMapper 以反/序列化 Java 8 日期时间值的最佳方法是什么?

更新:接受的答案并没有真正解决我的问题(阅读评论中的讨论)。我最终得到的代码比我在上面提出的要简单一些。也请参阅我自己的答案。

最佳答案

您不需要为 JSR-310 编写自定义序列化程序和反序列化程序类型。 Jackson 有一个自定义模块来处理这个问题,并将为您提供 serializerdeserializer你需要。

首先将 jackson-datatype-jsr310 工件添加到您的依赖项中:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9</version>
</dependency>

然后注册 JavaTimeModule在你的模块 ObjectMapper :

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

大多数 JSR-310 类型将使用标准的 ISO-8601 字符串表示进行序列化。如果您需要自定义格式,您可以使用自己的序列化器和反序列化器实现。

参见 documentation了解详情。

关于java - Java 8 时间 API 的 ObjectMapper 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49978441/

相关文章:

java - 没有检索到 GPS 更新?代码有问题?

java - 使用 Jackson 将 Guava Optional<Integer> 序列化为字符串

java - 如何将以毫秒为单位的 java.time.LocalTime 映射为以毫秒为单位的 java.sql.Time

java - 如何在 REST assured 中调用 put 方法

java - RabbitMQ - 线程 "main"java.lang.NoClassDefFoundError : org/slf4j/LoggerFactory 中出现异常

java - 针对 log4j1 编写的组件在 log4j2 升级后未记录

java - 如何为 Jackson 编写一个包罗万象的(反)序列化器

java - 使用 Jackson 映射 Json 时出现问题

java-8 - 为什么 Java 8 DateTimeFormatter 在 ResolverStyle.STRICT 模式下允许不正确的月份值?

java - java - 如何在java中将时间四舍五入到最近的一刻钟?