如何禁用Jackson从时代毫秒对Instant进行反序列化?

Did*_*cus 7 java datetime jackson jsr310 spring-boot

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

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

我可以在Instant字段中使用Jackson注释,还是可以设置属性以应用这种行为?还是自定义解串器是我唯一的选择?

Mar*_* R. 5

我可以在“即时”字段中使用杰克逊注释,还是可以设置以应用这种行为的属性?还是自定义解串器是我唯一的选择?

我个人并不了解可以为您开箱即用的注释。但是以下是完成此工作的简单反序列化器:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

    public class MyDTO {
        @JsonDeserialize(using = JacksonInstantDeserializer.class)
        public Instant instant;
    }
Run Code Online (Sandbox Code Playgroud)

GitHub上的完整代码

希望这可以帮助。

  • 为了提供更多帮助,我必须将反序列化器包装在向对象映射器注册的模块中。我在反序列化器上放置了一个静态方法来协助:`public static SimpleModule instantDeserializingModule() { var module = new SimpleModule(); module.addDeserializer(Instant.class, new JacksonInstantDeserializer()); 返回模块;}` 然后 `new ObjectMapper().registerModule(instantDeserializingModule())` (2认同)