当前位置: 首页 > 知识库问答 >
问题:

使用Jackson从字符串反序列化LocalDateTime

邓令雪
2023-03-14

我正在尝试使用Jackson将String反序列化为LocalDateTime,但它不起作用。

我有一个带有LocalDateTime字段的数据类:

@Data
public class Registration {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private LocalDateTime timestamp;
}

我添加了特殊的Jackson数据类型模块:

compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")

序列化可以在以下情况下正常工作:

new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(registration);

结果字符串:

{"timestamp":"2018-09-03 10:09:35"}

但反序列化不适用于:

new ObjectMapper().registerModule(new JavaTimeModule()).readValue(json.traverse(), Registration.class)

作为错误,我得到:

Cannot deserialize value of type `java.time.LocalDateTime` from String "2018-09-03 10:09:35": 
    Failed to deserialize java.time.LocalDateTime: 
        (java.time.format.DateTimeParseException) Text '2018-09-03 10:09:35' could not be parsed: 
            Unable to obtain LocalDateTime from TemporalAccessor: 
                {MinuteOfHour=9, NanoOfSecond=0, SecondOfMinute=35, MicroOfSecond=0, MilliOfSecond=0, HourOfAmPm=10},
                ISO resolved to 2018-09-03 of type java.time.format.Parsed

我错过了什么?我对串行化有效而反序列化无效感到困惑。

MWE:(小格拉德尔Java项目)

Main.java:

import java.io.IOException;
import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class Main {

    public static void main(String[] args) throws IOException {
        Registration registration = new Registration();
        registration.setTimestamp(LocalDateTime.now());

         ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());

         String s = objectMapper.writeValueAsString(registration);
         TreeNode treeNode = objectMapper.readTree(s);

         //Fails here:
         Registration registration1 = objectMapper.readValue(treeNode.traverse(), Registration.class);

        System.out.println(registration1);
    }
}

class Registration {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private LocalDateTime timestamp;

    public Registration() {
    }

    public LocalDateTime getTimestamp() {
        return this.timestamp;
    }

    public void setTimestamp(LocalDateTime localDateTime) {
        this.timestamp = localDateTime;
    }
}

build.gradle

plugins {
    id 'java'
}

group 'dateMWE'
version '1.0-SNAPSHOT'

sourceCompatibility = 10

repositories {
    mavenCentral()
}

dependencies {
    compile("com.fasterxml.jackson.core:jackson-annotations:2.9.6")
    compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.6")
}

共有2个答案

戈嘉慕
2023-03-14

您的ObjectMapper不受Spring管理,因为您正在使用new创建对象。在配置文件中将ObjectMapper配置为Bean。您需要使用LocalDateTimeDeserializer注册DateTimeFormat。然后在JavaTimeModule中设置您的Deserializer。

@Bean
 Public ObjectMapper objectMapper() {
   JavaTimeModule module = new JavaTimeModule();
   LocalDateTimeDeserializer localDateTimeDeserializer =  new 
   LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
   module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
   ObjectMapper objectMapperObj = Jackson2ObjectMapperBuilder.json()
            .modules(module)
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build();
return objectMapperObj ;

在您的Spring配置中设置上述配置。

齐成和
2023-03-14

问题与JSON反序列化无关,而是与时间格式字符串有关:

pattern = "yyyy-MM-dd hh:mm:ss"

请注意,小时设置为hh:这是一个12小时格式,需要“AM”或“PM”值。

如果模式被改变为

pattern = "yyyy-MM-dd HH:mm:ss"

这个问题应该得到解决。

 类似资料:
  • 问题内容: 我有以下类,它是由Jackson映射的(简化版): 在某些情况下,服务器会返回,然后我想将name设置为空的Java String。 是否有任何Jackson注释,或者如果属性为,我应该只检查getter中的null并返回空字符串? 问题答案: 您可以在默认构造函数中或声明时进行设置: 要么

  • 我有以下由Jackson映射的类(简化版): 在某些情况下,服务器返回,然后我想将name设置为空Java字符串。 是否有任何Jackson注释,或者如果属性为,我应该只检查getter中的null并返回空字符串吗?

  • 问题内容: 我有一张看起来像这样的地图: 我的动词类如下: 我想序列化和反序列化我的VerbResult类的实例,但是当我这样做时,出现此错误: 我在网上阅读了您需要告诉杰克逊如何反序列化地图键的信息,但是我没有找到任何信息来解释如何进行此操作。动词类也需要在映射之外进行序列化和反序列化,因此任何解决方案都应保留此功能。 问题答案: 在此处给出的答案的基础上,建议使用反序列化器实现模块。所述Jod

  • 我想序列化和反序列化我的VerbResult类的实例,但是当我这样做时,我得到了这个错误:的(映射)键反序列化器 我在网上读到,你需要告诉杰克逊如何反序列化地图键,但我没有找到任何信息解释如何去做这件事。verb类也需要在映射之外进行序列化和反序列化,因此任何解决方案都应该保留此功能。

  • 问题内容: 类型1(docs链接): 类型2(docs链接): 尽管以上两种类型都能完成任务,但这些实现之间有什么区别? 问题答案: 构造之后,两者都调用相同的反序列化功能,因此唯一的区别是泛型类型的处理方式。 第二个是完全静态的,因此类型必须在编译类型中是已知的,并且不能改变。因此,它类似于使用基本Class文字。 第一个是动态的,因此可以用于构造因其参数设置而变化的事物。 就我个人而言,我更喜

  • 问题内容: 我正在使用Spring的MappingJacksonHttpMessageConverter将JSON消息转换为控制器中的对象。 对于声明为ArrayList的字段,如果json消息包含一个String,则将引发以下异常: 一个例子是下面的类定义: 传入的Json在哪里: 如您所见,这将产生异常,因为图像应该是数组。 我想使自定义解串器更加宽容。如果反序列化失败,则从String中创建