LocalDateTime - 使用LocalDateTime.parse进行反序列化

23

我有一个字段 initiationDate,它通过 ToStringSerializer 类序列化为 ISO-8601 格式。

@JsonSerialize(using = ToStringSerializer.class)
private LocalDateTime initiationDate;

当我收到以下JSON时:

...
"initiationDate": "2016-05-11T17:32:20.897",
...

我想通过LocalDateTime.parse(CharSequence text)工厂方法进行反序列化。 我的所有尝试都以com.fasterxml.jackson.databind.JsonMappingException结束:

无法从String值('2016-05-11T17:32:20.897')实例化类型为[简单类型,类java.time.LocalDateTime]的值;没有单个String构造函数/工厂方法

我该如何做到这一点? 如何指定工厂方法?


编辑:

通过将jackson-datatype-jsr310模块包含到项目中并使用@JsonDeserializeLocalDateTimeDeserializer解决了该问题。

@JsonSerialize(using = ToStringSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime initiationDate;

1
我不知道它是否使用了 parse,但是你是否已经添加了适当的扩展,在这里 - Sotirios Delimanolis
1
@SotiriosDelimanolis,不,它如何解决我的问题?我需要指定工厂方法。 LocalDateTime.parse("2016-05-11T17:32:20.897") 可以正常工作。 - Andrew Tobilko
3个回答

31

Vanilla Jackson 没有一种方法可以从任何JSON字符串值中反序列化出一个LocalDateTime对象。

你有几个选项。你可以创建并注册自己的JsonDeserializer,它将使用LocalDateTime#parse方法。

class ParseDeserializer extends StdDeserializer<LocalDateTime> {
    public ParseDeserializer() {
        super(LocalDateTime.class);
    }

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return LocalDateTime.parse(p.getValueAsString()); // or overloaded with an appropriate format
    }
}
...
@JsonSerialize(using = ToStringSerializer.class)
@JsonDeserialize(using = ParseDeserializer.class)
private LocalDateTime initiationDate;

或者您可以将Jackson的java.time扩展添加到您的类路径中,并向您的ObjectMapper注册相应的Module

objectMapper.registerModule(new JavaTimeModule());

让Jackson帮你进行转换。在内部,它使用LocalDateTime#parse其中一个标准格式。幸运的是,它支持像这样的值:

and let Jackson do the conversion for you. Internally, this uses LocalDateTime#parse with one of the standard formats. Fortunately, it supports values like
2016-05-11T17:32:20.897

出类拔萃。


2
谢谢,第二种方法对我来说更好看,我使用了@JsonDeserialize而不是模块注册。 - Andrew Tobilko
是的,我也选择了第二种方式:objectMapper.registerModule(new JavaTimeModule());。我点了赞。 - Yan Khonski

9
对于那些想要解析自定义日期时间格式的人。
1)添加依赖项。
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.8"

2) 使用日期时间格式的Json注解

public class ClientRestObject {

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;

}

3)在ObjectMapper中注册Java8模块

private static ObjectMapper buildObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    //To parse LocalDateTime
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}

@András,你是说当你进行POST请求时,ClientRestObject中的LocalDateTime为空吗?我也遇到了同样的问题,想知道你是如何解决的。 - Steve
也许有点晚了,但请查看这里的被接受的答案:https://dev59.com/HlkS5IYBdhLWcg3wJDUP - caniaskyouaquestion

0
ObjectMapper objectMapper = new ObjectMapper();
//To parse LocalDateTime
objectMapper.registerModule(new JavaTimeModule());

这对我有用,谢谢!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接