【问题标题】:How to disable Jackson from deserializing an Instant from epoch millis?如何禁用杰克逊从纪元毫秒反序列化即时?
【发布时间】:2019-10-03 03:09:42
【问题描述】:

我正在使用 Spring Boot 开发 API,并且正在使用 Jackson 进行有效负载(反)序列化。我想将 ISO-8601 格式的日期时间反序列化为 java.time.Instant,但不想支持以毫秒或纳秒为单位从纪元时间反序列化。我只想支持以一种格式提供给我的 API 的数据,以减少客户端出错的机会。

目前,Jackson 将 ISO-8601 格式的字符串和仅包含数字的字符串反序列化为 Instant,例如"20190520".

我是否可以在 Instant 字段上使用 Jackson 注释,或者我可以设置属性以应用这种行为?还是自定义反序列化器是我唯一的选择?

【问题讨论】:

  • 我认为没有设置可以启用此功能。编写自己的自定义 JsonSerializer 应该是唯一的方法,即@JsonSerialize(using = CustomSerializer.class) private Instant time;

标签: java spring-boot datetime design-patterns jackson


【解决方案1】:

我是否可以在 Instant 字段上使用 Jackson 注释,或者我可以设置属性以应用这种行为?还是自定义反序列化器是我唯一的选择?

我个人不知道可以为您开箱即用的注释;但以下是完成这项工作的简单反序列化程序:

import java.io.IOException;
import java.time.Instant;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

public class JacksonInstantDeserializer extends StdDeserializer<Instant> {
    public JacksonInstantDeserializer() { this(null); }
    public JacksonInstantDeserializer(Class<?> clazz) { super(clazz); }

    @Override
    public Instant deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
        return Instant.parse(parser.getText());
    }
}

它基本上使用Instant.parse;它接受 ONLY 一个 ISO-8601 formatted string (如果字符串没有相应地格式化,它将抛出一个 DateTimeParseException )并根据其表示创建一个 Instant 。然后您可以使用 tell jackson 使用此转换器以下列方式反序列化您的 DTO 的 Instant 属性:

    public class MyDTO {
        @JsonDeserialize(using = JacksonInstantDeserializer.class)
        public Instant instant;
    }

Complete code on GitHub

希望这会有所帮助。

【讨论】:

  • 谢谢,我想我必须制作一个自定义的反序列化器。太糟糕了,Jackson 不支持禁用整数时间戳解析。
  • 为了提供更多帮助,我不得不将反序列化器包装在一个使用对象映射器注册的模块中。我在反序列化器上放了一个静态方法来辅助:public static SimpleModule instantDeserializingModule() { var module = new SimpleModule(); module.addDeserializer(Instant.class, new JacksonInstantDeserializer()); return module; } 然后new ObjectMapper().registerModule(instantDeserializingModule())
  • @Marco 非常感谢您的回答,真的帮助了我,就我而言,json 文件不是字符串,它是 unix 时间戳值,所以我不得不使用它而不是解析 @ 987654333@
  • @AyaAki 不客气,很高兴为您提供帮助。太糟糕了,stackoverflow 的评分系统太糟糕了,否则我会像这个一样详细回答更多问题。 Stackoveflow 只是出于某种奇怪的原因拿走了我的一大笔积分。和他们一起完成!我可能会创建自己的博客并在那里完成我所有的工作。
猜你喜欢
  • 2017-11-09
  • 2016-10-26
  • 2019-10-14
  • 2015-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-20
  • 2016-01-27
相关资源
最近更新 更多