如何解决是否有 Spring Boot 标志来禁用随时间对 LocalDate 值进行宽松的 Jackson 解析?
Spring Boot 默认允许 LocalDate
中的日期和日期时间值。
例如对于以下 DTO:
public class Person {
private LocalDate birthDate;
//getter & setters
}
以下两种情况都是可以接受的:
{
"birthDate" : "2021-07-24"
}
{
"birthDate" : "2021-07-24T17:00:00Z"
}
Jackson 有一个 lenient
标志,可以设置为拒绝带有时间的日期:
@JsonFormat(pattern="uuuu-MM-dd",lenient = OptBoolean.FALSE)
private LocalDate birthDate;
是否有对应的Spring Boot应用属性标志,可以设置全局应用到所有LocalDate
字段,这样注解就不需要每一个LocalDate
字段都加定义一个像 this?
解决方法
我自己在本地对此进行了测试,看来 input
注释元素不是导致日期时间值被拒绝的原因,而是 lenient
元素的存在。因此,这足以拒绝日期时间值:
format
也就是说,Jackson 2.13 正在改变 @JsonFormat(pattern="uuuu-MM-dd")
private LocalDate birthDate;
标志的行为,这样当日期时间值为 false (jackson-modules-java8#212) 时将被拒绝。对于 Jackson 2.13(在撰写本文时尚未发布),以下内容也足以使用默认的 lenient
ISO 格式拒绝日期时间值:
LocalDate
至于您关于配置日期格式的全局标志的主要问题,我在 Jackson 中没有看到任何功能标志来全局配置它,这排除了直接配置 @JsonFormat(lenient = OptBoolean.FALSE)
private LocalDate birthDate;
的 spring.jackson
属性具有内置的 Jackson 功能。
有一个 spring.jackson.date-format
应用程序属性,看起来可以用于此目的。但是,进一步研究该属性,它似乎仅用于使用 java.text.DateFormat
的旧 Java 日期类型,而不用于新的 ObjectMapper
类型。这在 Jackson 问题 #3132 中有简要说明:
不幸的是,Java 8 日期/时间格式字符串应用程序与“旧 JDK”类型不同; java.time
根本无法使用。
Spring Boot 问题 #27547 是一项功能请求,用于添加标志以通过应用程序属性全局配置 DateFormat
设置。
我不知道是否有这样的属性,但您可以通过配置 ObjectMapper
来实现这一点。配置类 (like here) 只需要几行代码,但如果还有其他需要全局配置的内容,那么最好使用它。
看看这个配置类:
@Configuration
public class JacksonConfiguration {
public static final String LOCAL_DATE_PATTERN = "yyyy-MM-dd";
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
JavaTimeModule timeModule = new JavaTimeModule();
timeModule.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter
.ofPattern(LOCAL_DATE_PATTERN)));
mapper.registerModule(timeModule);
return mapper;
}
}
Jackson 使用 JavaTimeModule
来解析 LocalDate
(和 LocalDateTime
)。 JavaTimeModule
包括默认反序列化器,似乎没有直接访问它们的方法,因此技巧是替换反序列化 LocalDate
的那个。如果在给定的 LocalDate(Time)
内也有时间,在示例中将模式显式设置为 1 将导致解析错误。
如您所见,似乎需要自定义反序列化器,但将其设置在配置类上并不是什么大问题。
,对于 2.12 之前的 Jackson 版本(截至撰写本文时的当前发布版本),将 lenient
标志设置为 false
实际上不会导致 Jackson 拒绝时间部分。 Jackson 2.13 将根据 jackson-modules-java8#212 对此进行更改,以便将 lenient
标志设置为 false 将导致带有时间的日期被拒绝。
据我所知,目前没有可用于禁用默认宽大处理的 Spring Boot 属性,尽管发出 #27547 请求添加了一个。但是,可以使用 ObjectMapper.setDefaultLeniency(Boolean b)
在 ObjectMapper
中配置默认宽大设置。因此,一旦 Jackson 2.13 发布,就可以在提供的 ObjectMapper
bean 上设置此标志,以实现拒绝带有时间组件的日期的预期目标。
禁用此功能的最直接方法可能是使用自定义 Jackson2ObjectMapperBuilderCustomizer
来配置 ObjectMapper
:
@Configuration
public class CustomizedJacksonConfiguration {
@Bean
public Jackson2ObjectMapperBuilderCustomizer nonLenientObjectMapperBuilderCustomizer() {
return builder -> builder.postConfigurer(
objectMapper -> objectMapper.setDefaultLeniency(false));
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。