SpringBoot 中的 JSON Java8 LocalDateTime 格式

在我的 SpringBootApplication 中,我在格式化 Java8LocalDateTime 时遇到了一个小问题。对于“正常”日期,我没有问题,但是 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;
}

但是上面的任何一个注释都不起作用,日期就像上面那样被格式化了。欢迎提出建议!

266616 次浏览

Update : 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格式打印

只有在需要更改日期格式时才需要注释。

我添加了 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"

在这里它是在专家,与属性,以便您可以生存之间的春季启动升级

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

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 Config.

@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;
}
}

我找到了另一个解决方案,您可以将其转换为您想要的任何格式,并应用于所有 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)

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

ZonedDateTime 的格式是: “2017-12-27T08:55:17.317 + 02:00[亚洲/耶路撒冷]” LocalDateTime 是: “2017-12-27T09:05:30.523”

这个工作很好:

添加依赖项:

<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());

@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();
}
}

写下这个答案也是为了提醒我。

我在这里综合了几个答案,最后我的答案是这样的。 (我使用的是 Springboot1.5.7和龙目岛1.16.16)

@Data
public Class someClass {


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


}

正如前面提到的,spring-boot 将获取所有您需要的信息(对于 web 和 webfluxstarter)。

但是更好的是——您不需要自己注册任何模块。 看看 给你。由于 @SpringBootApplication在引擎盖下使用 @EnableAutoConfiguration,这意味着 JacksonAutoConfiguration将被自动添加到上下文中。 现在,如果你看看 JacksonAutoConfiguration内部,你会看到:

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

在初始化过程中将调用这个 guy ,并获取它在类路径中找到的所有模块。 (我使用 Spring Boot 2.1)

我正在使用 Springboot2.0.6,由于某些原因,应用程序 yml 的更改无法工作。 而且我还有更多的要求。

我尝试创建 ObjectMapper 并将其标记为 Prime,但是弹簧引导抱怨说我已经将 jacksonObjectMapper 标记为 Prime! !

我就是这么做的。 我修改了内部映射器。

我的序列化器和反序列化器是特殊的-他们处理‘ 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;
}

简单使用:

@JsonFormat(pattern="10/04/2019")

或者你可以使用你喜欢的模式,例如: ('-' in place of '/')

我使用的是 SpringBoot2.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"

这招对我很管用。

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
public Class someClass {


@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime sinceDate;


}


补充

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

进入渐变编译块

application.yml文件中

spring:
jackson:
serialization:
write_dates_as_timestamps: false

如果您使用的是 application.properties文件 添加以下内容

spring.jackson.serialization.write_dates_as_timestamps=false

如果要应用自定义格式,可以应用注释

    @JsonFormat(pattern = "yyyy-MMMM-dd hh:mm:ss")
private LocalDateTime date;

我开始觉得还不错

这招对我很管用。

我在我的 DTO 中定义了 生日字段,如下所述:

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

在我的 请求身体中,我以如下格式通过了 生日:

{
"birthDate": "2021-06-03 00:00:00"
}

下面的注释对我很有用

@JsonSerialize(using = LocalDateSerializer.class) and
@JsonFormat(pattern="yyyy-MM-dd")