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

如何在LocalDateTime和LocalDate for Java上配置Jackson序列化?

慕鸿波
2023-03-14

我知道Stackoverflow上有很多关于这个主题的帖子,我确信我已经阅读了几乎所有的帖子,但我仍在努力让它发挥作用,希望能得到任何指导。

这是我使用的Spring家长和Jackson依赖项:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>

<!-- Jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

在我的应用程序配置中,我尝试使用:

@Autowired
void configureJackson(ObjectMapper jackson2ObjectMapper) {

    JavaTimeModule timeModule = new JavaTimeModule();

    timeModule.addDeserializer(LocalDate.class,
            new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

    timeModule.addDeserializer(LocalDateTime.class,
            new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    timeModule.addSerializer(LocalDate.class,
            new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

    timeModule.addSerializer(LocalDateTime.class,
            new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    jackson2ObjectMapper
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .registerModule(timeModule)
            .registerModule(new ParameterNamesModule())
            .registerModule(new Jdk8Module())
            .registerModule(new JtsModule());
}

这是我正在测试的模型。(我试图在5-6个模型中达到相同的效果)。

public class DateRange implements Serializable {

     private static final long serialVersionUID = 6412487507434252330L;

     private LocalDateTime startTime;
     private LocalDateTime endTime;

     private LocalDate startDate;
     private LocalDate endDate;

     // Getters/Setters

我希望我能找到一种适用于全球的方法,而不需要我单独注释每个字段。我在使用java.util。日期之前,但在其他功能方面遇到了一些问题。

试图使用这些更新(更好)的日期模型,而不是旧的损坏一个引起了我很多头痛的一件简单的事情。

更新

我将我的配置更改为下面建议的配置之一,非常接近解决这个问题。

@Bean
@Primary
public ObjectMapper objectMapper() {

    JavaTimeModule timeModule = new JavaTimeModule();

    timeModule.addDeserializer(LocalDate.class,
            new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

    timeModule.addDeserializer(LocalDateTime.class,
            new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    timeModule.addSerializer(LocalDate.class,
            new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

    timeModule.addSerializer(LocalDateTime.class,
            new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    return new ObjectMapper()
            //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .registerModule(timeModule)
            .registerModule(new ParameterNamesModule())
            .registerModule(new Jdk8Module())
            .registerModule(new JtsModule());
}

现在我唯一的问题是LocalDateTime在需要时打印时间戳,如:“2018-07-26T07:57:12.938”,如:2018-07-26 07:57:12。

这些字段今天已经在使用,我需要以一种不需要API消费者进行任何调整的方式无缝地进行更改。

Cassio提到禁用SerializationFeature。WRITE\u DATES\u AS\u TIMESTAMPS将以这种ISO格式打印时间戳,但这不是我需要的。我试图注释掉这个字段,希望它能找到我提供的自定义日期时间格式,但它并没有改变我的输出。

共有3个答案

嵇丰
2023-03-14

您还可以解决此问题以公开此实例:

@Bean
public Jackson2ObjectMapperBuilder configureObjectMapper() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.modules(new JavaTimeModule(),new ParameterNamesModule(),new Jdk8Module());
    builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    return builder;
}
曾宏毅
2023-03-14

在Cassio和其他一些网络挖掘的帮助下,我终于做到了这一点。回顾过去,我认为问题在于我在JavaTimeModule上定义了自定义格式,但我需要在映射器上定义它们。

@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
    return new Jackson2ObjectMapperBuilder()
            .createXmlMapper(false)
            .indentOutput(true)
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .serializers(
                    new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
                    new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
            .deserializers(
                    new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
                    new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
            .modules(
                    new JavaTimeModule(),
                    new ParameterNamesModule(),
                    new Jdk8Module(),
                    new JtsModule());
}

https://github.com/spring-projects/spring-boot/issues/4217

http://www.baeldung.com/jackson-serialize-dates

毋城
2023-03-14

JavaTimeModule将为您完成艰苦的工作。它为java.time类型提供了一组序列化器和反序列化器。如果SerializationFeature.WRITE_DATES_AS_TIMESTAMPS被禁用,java.time类型将在标准ISO-8601字符串表示中序列化。

默认情况下,Spring将为您提供由Jackson2ObjectMapperBuilder创建的ObjectMappper的实例。此实例是为您自动配置的。有关详细信息,请参阅类留档。

如果要完全替换默认的ObjectMapper,请定义该类型的@Bean并将其标记为@主

@Bean
@Primary
public ObjectMapper objectMapper() {    
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    return mapper;
}

或者,如果您更喜欢基于生成器的方法,请定义一个Jackson2ObjectMapperBuilder。

@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.modules(new JavaTimeModule());
    builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    return builder;
}

请注意,在任何一种情况下,这样做都会禁用ObjectMapper的所有自动配置。有关详细信息,请参阅留档。

 类似资料:
  • 我得到了以下代码: 我得到了这个: {"时间":{"小时": 20,"分钟": 49,"秒": 42,"纳米": 99000000,"一天": 19,"一天":"星期四","月":"一月","一天": 19,"年": 2017,"月值": 1,"年表":{"id":"ISO","calendarType":"iso8601"}}} 我要实现的是ISO8601中的字符串 2017-01-19T18:

  • 我正在使用JavaSpring-boot RestController。我有一个示例GET API,在其中我将LocalDateTime.now()发送到响应正文中。我已经自定义了Jackson ObjectMapper来注册jackson-datatype-jsr310模块,但是它无法序列化LocalDateTime实例。我尝试了许多不同的在线解决方案,但是似乎都不起作用。下面提到了我在这里发布

  • 我有一个使用以下方法的会话豆: 返回的CalculationResult无法映射到JSON,并出现以下异常: 如何在 Wildfly 中配置杰克逊及其?

  • 问题内容: 我有两个要使用Jackson序列化为JSON的Java类: 我想将Item序列化为此JSON: 用户序列化为仅包含。我还将能够将所有用户对象序列化为JSON,例如: 所以我想我需要为此编写一个自定义的序列化程序并尝试过: 我使用来自Jackson How-to:Custom Serializers的 代码对JSON进行了序列化: 但是我得到这个错误: 如何在Jackson上使用自定义序

  • 我正在尝试使用Jackson将反序列化为,但它不起作用。 我有一个带有LocalDateTime字段的数据类: 我添加了特殊的Jackson数据类型模块: 序列化可以在以下情况下正常工作: 结果字符串: 但反序列化不适用于: 作为错误,我得到: 我错过了什么?我对串行化有效而反序列化无效感到困惑。 MWE:(小格拉德尔Java项目) Main.java: build.gradle:

  • 问题内容: 我有一个使用以下方法的会话Bean: 返回的CalculationResult无法映射到JSON,并且发生以下异常: 如何在中配置Jackson及其及其? 问题答案: “如何在Wildfly中配置Jackson及其序列化功能?” 你不需要在Wildfly中进行配置,可以在JAX-RS应用程序中进行配置。只需使用即可配置即可(请参阅此处的更多信息)。就像是 如果你还没有Jackson依赖