无法使用 Jackson 将 java.time.LocalDate 序列化为字符串

Posted

技术标签:

【中文标题】无法使用 Jackson 将 java.time.LocalDate 序列化为字符串【英文标题】:Can't serialize java.time.LocalDate as a String with Jackson 【发布时间】:2016-01-02 07:49:40 【问题描述】:

我正在使用 spring-boot 1.2.1.RELEASE 和 jackson 2.6.2,包括 jsr310 数据类型。我正在使用注释 @SpringBootApplication 来启动我的 Spring 应用程序。我有

spring.jackson.serialization.write_dates_as_timestamps = false

在我的 application.properties 中设置(我知道正在读取它,因为我使用banner = false 进行了测试)。

然而 java.time.LocalDate 仍然被序列化为一个整数数组。我没有使用@EnableWebMvc。

如果我添加标签看起来像

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")

到我的 LocalDate 变量然后它工作。但我认为上面的属性集是自动的。另外,如果我没记错的话(我刚刚决定使用整数数组),那只适用于序列化而不是反序列化(但老实说,我不太记得最后一部分是否属实)。

【问题讨论】:

你注册JSR310的Jackson模块了吗? objectMapper.registerModule(new JavaTimeModule()); 这是由 spring-boot 自动完成的,我知道这是因为没有 jackson-datatype-jsr310 添加到我的 pom.xml 中,我得到了 LocalDate 的默认复杂序列化。当我添加数据类型时,我得到了整数数组序列化。 Wrt 反序列化:无论序列化设置如何,这两种形式都应该是可以接受的。但是,如果您使用自定义文本格式,则反序列化也需要这样做。 几年前我更新到 spring boot 2.X(目前在 2.1.9.RELEASE),所有这些都是不必要的。开箱即用,它转换为字符串,无需配置。 【参考方案1】:

这是 Spring Boot 中的 know issue。您需要手动完成。

objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

或更新到 1.2.2。

更新: 还有一个 way to configure ObjectMapper 由您的容器中的 spring 使用。

【讨论】:

我现在在 1.2.6 上,它仍然忽略该属性。另外,如何在不使用 WebMvc 的情况下访问 objectMapper?我发现的所有网络事件都涉及使用我没有使用的 WebMvc。 添加了答案链接 看起来根据该答案,属性配置在 1.3 发布之前将不可用。感谢您提供的链接。【参考方案2】:

这个问题以一种奇怪的方式发生在我身上......使用不同的弹簧配置文件,其中一个返回整数数组,另一个返回预期结果(年-月-日)。

查看我的配置后,问题是我的班级缺少@Configuration 和(可能)@Primary...这不能解释为什么可以在不同的配置文件中工作,但是这个后续设置解决了我的问题:

@Configuration
public class WebConfigurer 

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) 
        ObjectMapper objectMapper = builder.build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    


当然,您仍然需要 pom.xml 中的 JSR 310 依赖项。

【讨论】:

【参考方案3】:

我遇到了同样的问题,LocalDateTime 被序列化为一个整数数组,比如[2019,10,14,15,7,6,31000000]。我的 Spring Boot 版本是 1.5.13.RELEASE。我必须在 ObjectMapper 上注册 JavaTimeModule 来解决这个问题。下面是我的 ObjectMapper 配置,对我有用:

@Bean
  public ObjectMapper getObjectMapper() 
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    mapper.registerModule(new JavaTimeModule());
    return mapper;
  

【讨论】:

以上是关于无法使用 Jackson 将 java.time.LocalDate 序列化为字符串的主要内容,如果未能解决你的问题,请参考以下文章

com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造`java.time.Instant`的实例(没有创建者,如默认构造

Spring Boot 问题使用 Jackson 序列化 java.time.LocalDateTime 以返回 ISO-8601 JSON 时间戳?

Jackson , java.time , ISO 8601 , 无毫秒序列化

如何使用 Jackson 和 java.time 解析不同的 ISO 日期/时间格式?

将毫秒时间戳反序列化为 java.time.Instant

是否有任何选项可以在 Spring Boot 中使用 Jackson 为 java.time.* 包注册一次 Serializer/Deserializer?