Spring Boot LocalDate 字段序列化和反序列化
Posted
技术标签:
【中文标题】Spring Boot LocalDate 字段序列化和反序列化【英文标题】:Spring Boot LocalDate field serialization and deserialization 【发布时间】:2015-09-01 11:43:28 【问题描述】:在 Spring Boot 1.2.3.RELEASE 中使用 fasterxml 将LocalDate
字段序列化和反序列化为 ISO 日期格式字符串的正确方法是什么?
我试过了:
spring.jackson.serialization.write-dates-as-timestamps:false
在 application.properties 文件中,
在项目中包含jackson-datatype-jsr310,然后使用
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
注解
和@DateTimeFormat(iso=ISO.DATE)
注解,
将Jsr310DateTimeFormatAnnotationFormatterFactory
添加为格式化程序:
@Override
public void addFormatters(FormatterRegistry registry)
registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
以上都没有帮助。
【问题讨论】:
【参考方案1】:compile ("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
在 build.gradle 中 然后以下注释有所帮助:
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthday;
更新:如果您使用的是 Spring Boot 2.*,则依赖项已通过“启动器”之一包含在内。
【讨论】:
这为我解决了问题。升级使用spring boot 1.3.0.BUILD.SNAPSHOT版本时遇到反序列化问题。 你能指定你的解决方案吗? 是的,您需要 com.fasterxml.jackson.datatype:jackson-datatype-jsr310 依赖项,然后您可以将@JsonDeserialize
@JsonSerialize
注释与 LocalDate 字段一起使用,就像答案中一样。
在 SpringBoot 1.3.6.RELEASE 上对我不起作用;/ 出现错误:com.fasterxml.jackson.datatype.jsr310.ser.JSR310FormattedSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Ljava/lang/Class;)Lcom/fasterxml/jackson/annotation/JsonFormat$Value;
解决了我的问题。使用 LocalDateTime 杰克逊反序列化,谢谢【参考方案2】:
在我的 Spring Boot 2 应用程序中
@JsonFormat
注解在(反)序列化 JSON 数据时在 REST 控制器中使用。
@DateTimeFormat
注解在其他控制器中使用 ModelAttribute
s 在(反)序列化字符串数据时。
您可以在同一个字段上指定两者(如果您在 JSON 和 Thymeleaf 模板之间共享 DTO,这很有用):
@JsonFormat(pattern = "dd/MM/yyyy")
@DateTimeFormat(pattern = "dd/MM/yyyy")
private LocalDate birthdate;
Gradle 依赖:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-json'
我希望这是您在 Spring Boot 2.x 应用程序中自定义日期/时间格式所需的所有配置。
对于 Spring Boot 1.x 应用,指定额外的注解和依赖:
@JsonFormat(pattern = "dd/MM/yyyy")
@DateTimeFormat(pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthDate;
// or
@JsonFormat(pattern = "dd/MM/yyyy HH:mm")
@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime birthDateTime;
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.8'
请注意,如果有人以错误的格式发送日期,您的 API 将抛出“JSON 解析错误”。映射示例:
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate releaseDate;
异常示例:
HttpMessageNotReadableException
:JSON 解析错误:无法从字符串“2002”反序列化java.time.LocalDate
类型的值:无法反序列化java.time.LocalDate
:(java.time.format.DateTimeParseException
)无法在索引 4 处解析文本“2002”;嵌套异常是com.fasterxml.jackson.databind.exc.InvalidFormatException
:无法从字符串“2002”反序列化java.time.LocalDate
类型的值:无法反序列化java.time.LocalDate
:(java.time.format.DateTimeParseException
)无法在索引4 处解析文本“2002”
【讨论】:
【参考方案3】:如果您想使用自定义 Java 日期格式化程序,请添加 @JsonFormat
注释。
@JsonFormat(pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthdate;*
【讨论】:
【参考方案4】:其实只要在 pom.xml 中指定依赖就可以了。
这样,我所有的 LocalDate 字段都会自动使用 ISO 格式,无需注释:
<!-- This is enough for LocalDate to be deserialized using ISO format -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
在 Spring Boot 1.5.7 上测试。
【讨论】:
【参考方案5】: @Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer()
return builder ->
DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
builder.serializerByType(LocalDate.class, new LocalDateSerializer(localDateFormatter));
builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(localDateFormatter));
DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));
;
【讨论】:
以上是关于Spring Boot LocalDate 字段序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Boot 2 和 Kotlin 进行 Jackson 反序列化,无法构造 `java.time.LocalDate` 的实例
如何在 Spring Boot 中为 Camel 配置 Jackson ObjectMapper
无法使用 Jackson 将 java.time.LocalDate 序列化为字符串