Spring Boot中的JSON Java 8 LocalDateTime格式


112

我在Spring Boot应用程序中格式化Java 8 LocalDateTime时遇到一个小问题。对于“正常”日期,我没有问题,但是LocalDateTime字段转换为以下内容:

"startDate" : {
    "year" : 2010,
    "month" : "JANUARY",
    "dayOfMonth" : 1,
    "dayOfWeek" : "FRIDAY",
    "dayOfYear" : 1,
    "monthValue" : 1,
    "hour" : 2,
    "minute" : 2,
    "second" : 0,
    "nano" : 0,
    "chronology" : {
      "id" : "ISO",
      "calendarType" : "iso8601"
    }
  }

虽然我想将其转换为:

"startDate": "2015-01-01"

我的代码如下所示:

@JsonFormat(pattern="yyyy-MM-dd")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
public LocalDateTime getStartDate() {
    return startDate;
}

但是以上任何一个注释都无法正常工作,日期的格式仍然像上面一样。建议欢迎!

Answers:


134

更新:Spring Boot 2.x不再需要此配置。我在这里写了一个最新的答案


(这是在Spring Boot 2.x之前执行此操作的方式,这对于使用较旧版本的Spring Boot的人员可能有用)

我终于在这里找到如何做。要修复它,我需要另一个依赖项:

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

通过包括这种依赖关系,Spring会自动注册一个转换器,它作为描述在这里。之后,您需要将以下内容添加到application.properties中:

spring.jackson.serialization.write_dates_as_timestamps=false

这将确保使用正确的转换器,并且日期将以以下格式打印 2016-03-16T13:56:39.492

仅在要更改日期格式的情况下才需要注释。


24
可能值得添加以下注释@JsonSerialize(using = LocalDateTimeSerializer.class)-...
Nick Grealy

3
application.properties如@patelb答案所示,最好仅使用一个条目。
membersound

不工作 但是patelib的答案开箱即用!
Mykhaylo Kopytonenko'17年

请注意,我们需要@JsonSerialize尼克提到的注释才能使其正常工作。
pennstatephil

92

我添加了com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1依赖性,并开始以以下格式获取日期:

"birthDate": [
    2016,
    1,
    25,
    21,
    34,
    55
  ]

这不是我想要的,但是我越来越近了。然后,我添加了以下内容

spring.jackson.serialization.write_dates_as_timestamps=false

到application.properties文件,该文件为我提供了所需的正确格式。

"birthDate": "2016-01-25T21:34:55"

2
包括jackson-datatype-jsr310依赖项时即开即用。这应该是公认的答案。
membersound

6
仅供参考,如果您使用以下方法配置ObjectMapper,可以通过Java config来完成application.properties部分:mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
justin

31

在这里,它具有特性,因此您可以在春季靴升级之间生存

<dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
</dependency>

1
将此解决方案与@NickGrealy注释一起使用:可能值得添加以下注释@JsonSerialize(using = LocalDateTimeSerializer.class)
HairOfTheDog

19

1)依赖

 compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.8.8' 

2)具有日期时间格式的注释。

public class RestObject {

    private LocalDateTime timestamp;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public LocalDateTime getTimestamp() {
        return timestamp;
    }
}

3)Spring配置

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        System.out.println("Config is starting.");
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }
}

2
非常感谢。@JsonFormat是为我解决它的人。上面的解决方案都不是出于某种原因对我
有用

7

我找到了另一个解决方案,您可以将其转换为所需的任何格式并应用于所有LocalDateTime数据类型,而不必在每个LocalDateTime数据类型上方指定@JsonFormat。首先添加依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

添加以下bean:

@Configuration
public class Java8DateTimeConfiguration {
    /**
     * Customizing
     * http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html
     *
     * Defining a @Bean of type Jackson2ObjectMapperBuilder will allow you to customize both default ObjectMapper and XmlMapper (used in MappingJackson2HttpMessageConverter and MappingJackson2XmlHttpMessageConverter respectively).
     */
    @Bean
    public Module jsonMapperJava8DateTimeModule() {
        val bean = new SimpleModule();

        bean.addDeserializer (ZonedDateTime.class, new JsonDeserializer<ZonedDateTime>() {
            @Override
            public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return ZonedDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
            }
        });

        bean.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
            @Override
            public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return LocalDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            }
        });

        bean.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
            @Override
            public void serialize(
                    ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                    throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(zonedDateTime));
            }
        });

        bean.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
            @Override
            public void serialize(
                    LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                    throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDateTime));
            }
        });

        return bean;
    }
}

在您的配置文件中添加以下内容:

@Import(Java8DateTimeConfiguration.class)

只要您使用的是spring创建的objectMapper,它将对所有属性LocalDateTime和ZonedDateTime进行序列化和反序列化。

您为ZonedDateTime获得的格式为:“ 2017-12-27T08:55:17.317 + 02:00 [Asia / Jerusalem]” for LocalDateTime为:“ 2017-12-27T09:05:30.523”


可能需要将val bean替换为SimpleModule bean = new SimpleModule();
Abhishek Galoda

这是Java 9吗?
Daniel Dai

@DanielDai这是Java 8
艾达阿米特

@Abhi,SimpleModule延伸ModuleModule是一个摘要。val bean = new SimpleModule(); 完美的作品。
艾达·阿米特

对于SpringBoot版本1.5.3,不必添加RELEASE来添加jackson-datatype-jsr310依赖项。
Moon13

7

写这个答案也提醒我。

我在这里结合了几个答案,最后我的工作就是这样的。(我正在使用SpringBoot 1.5.7和Lombok 1.16.16)

@Data
public Class someClass {

   @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
   @JsonSerialize(using = LocalDateTimeSerializer.class)
   @JsonDeserialize(using = LocalDateTimeDeserializer.class)
   private LocalDateTime someDate;

}

1
您可能想为DateTimeFormat和其他人添加导入。
祈祷的

4

这项工作很好:

添加依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>

添加注释:

@JsonFormat(pattern="yyyy-MM-dd")

现在,您必须获取正确的格式。

要使用对象映射器,您需要注册JavaTime

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

1

如前所述,spring-boot将获取您需要的所有内容(对于web和webflux启动器)。

但是更好的是-您不需要自己注册任何模块。在这里看看。由于在后台@SpringBootApplication使用@EnableAutoConfiguration,因此意味着JacksonAutoConfiguration将自动添加到上下文中。现在,如果您向内看JacksonAutoConfiguration,您将看到:

    private void configureModules(Jackson2ObjectMapperBuilder builder) {
        Collection<Module> moduleBeans = getBeans(this.applicationContext,
                Module.class);
        builder.modulesToInstall(moduleBeans.toArray(new Module[0]));
    }

该分类将在初始化过程中调用,并将获取其在类路径中可以找到的所有模块。(我使用Spring Boot 2.1)


1

我正在使用Springboot 2.0.6,由于某种原因,应用yml的更改无法正常工作。而且我还有更多要求。

我尝试创建ObjectMapper并将其标记为Primary,但是Spring Boot抱怨我已经将jacksonObjectMapper标记为Primary!

这就是我所做的。我对内部映射器进行了更改。

我的序列化器和反序列化器很特殊-它们处理'dd / MM / YYYY';并且在反序列化时-它会尽力使用3-4种流行格式来确保我有一些LocalDate。

@Autowired
ObjectMapper mapper;

@PostConstruct
public ObjectMapper configureMapper() {
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

    mapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, true);
    mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

    SimpleModule module = new SimpleModule();
    module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
    module.addSerializer(LocalDate.class, new LocalDateSerializer());
    mapper.registerModule(module);

    return mapper;
}

0

@JsonDeserialize(using= LocalDateDeserializer.class) 以下依赖性对我不起作用。

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version> 2.9.6</version>
</dependency>

我使用以下代码转换器将日期反序列化为java.sql.Date

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;


@SuppressWarnings("UnusedDeclaration")
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<java.time.LocalDate, java.sql.Date> {


    @Override
    public java.sql.Date convertToDatabaseColumn(java.time.LocalDate attribute) {

        return attribute == null ? null : java.sql.Date.valueOf(attribute);
    }

    @Override
    public java.time.LocalDate convertToEntityAttribute(java.sql.Date dbData) {

        return dbData == null ? null : dbData.toLocalDate();
    }
}


0

我正在使用Spring Boot 2.1.8。我已经进口了

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
</dependency>

其中包括jackson-datatype-jsr310

然后,我必须添加这些注释

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty("date")
LocalDateTime getDate();

而且有效。JSON如下所示:

"date": "2020-03-09 17:55:00"

提示:spring-boot-starter-json仅在spring-boot-starter-web缺少时才需要包含。
judomu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.