SGB*_*SGB 5 java date-parsing date-formatting jackson spring-boot
Spring Boot 默认允许LocalDate.
例如对于以下 DTO:
public class Person {
private LocalDate birthDate;
//getter & setters
}
Run Code Online (Sandbox Code Playgroud)
以下两种情况都是可以接受的:
{
"birthDate" : "2021-07-24"
}
Run Code Online (Sandbox Code Playgroud)
{
"birthDate" : "2021-07-24T17:00:00Z"
}
Run Code Online (Sandbox Code Playgroud)
Jackson 有一个lenient可以设置为拒绝日期和时间的标志:
@JsonFormat(pattern="uuuu-MM-dd", lenient = OptBoolean.FALSE)
private LocalDate birthDate;
Run Code Online (Sandbox Code Playgroud)
是否有相应的 Spring Boot 应用程序属性标志可以设置为全局应用于所有LocalDate字段,以便不需要将注释添加到每个LocalDate字段,也不需要像这样定义自定义反序列化器?
在解决全局设置标志的问题之前lenient,值得注意的是,在这个特定示例(在 2.13.0 之前的 Jackson 版本中编写)中设置此标志并没有真正达到预期的结果。pattern相反,导致值被拒绝的是注释元素的存在,而不是lenient注释元素。因此,以下内容足以拒绝示例日期时间值:
@JsonFormat(pattern="uuuu-MM-dd")
private LocalDate birthDate;
Run Code Online (Sandbox Code Playgroud)
关于在 Spring Boot 应用程序中全局设置标志的问题lenient,这个问题的答案取决于所使用的 Spring Boot 和 Jackson 的版本,因为这些库的较新版本已经添加了围绕此行为的功能。
使用 Spring Boot 2.6.0 和 Jackson 2.13.0,spring.jackson.default-leniency可以将应用程序属性设置false为达到所需的结果。
spring.jackson.default-leniency: false
Run Code Online (Sandbox Code Playgroud)
从 Jackson 2.13.0 开始,当基础类型是不带时间的日期时,设置lenient标志导致带时间的日期被拒绝 ( jackson-modules-java8#212 )。false
Spring Boot 2.6.0 添加了spring.jackson.default-leniency标志来配置 Spring Boot 提供的ObjectMapperbean 上的默认宽松度 ( spring-boot#27547 )。
因此,结合这两个库版本并利用该spring.jackson.default-leniency标志可以实现拒绝具有时间分量的日期值的预期结果LocalDate。
Spring Boot 2.5.x 没有应用程序属性来设置 Spring Boot 提供的ObjectMapperbean 的默认宽松度。但是,可以通过其他方式自定义此 bean 以设置默认的宽大程度。如上所述,这将达到在 Jackson 2.13.x 或更高版本中拒绝带有时间的日期的预期结果。
在 Spring Boot 2.5.x 应用程序中设置默认宽松度的最直接方法可能是使用自定义Jackson2ObjectMapperBuilderCustomizerbean 来配置ObjectMapper:
@Configuration
public class CustomizedJacksonConfiguration {
@Bean
public Jackson2ObjectMapperBuilderCustomizer nonLenientObjectMapperBuilderCustomizer() {
return builder -> builder.postConfigurer(
objectMapper -> objectMapper.setDefaultLeniency(false));
}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,将lenient标志设置为false实际上不会导致 2.13 之前的 Jackson 版本拒绝带有时间部分的值。
我不知道是否有这样的属性,但您可以通过配置您的ObjectMapper. 配置类(就像这里)需要几行代码,但最好有一些代码,以防万一还有其他东西需要全局配置。
看一下这个配置类:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
Jackson 用来JavaTimeModule解析LocalDate(and LocalDateTime)。JavaTimeModule包括默认的反序列化器,并且似乎没有直接的方法来访问它们,因此技巧是替换反序列化器LocalDate。在示例中将模式显式设置为 1 时,如果给定的时间范围内也有时间,则会导致解析错误LocalDate(Time)。
正如您所看到的,似乎需要一个自定义反序列化器,但在配置类上设置它并不是什么大问题。
| 归档时间: |
|
| 查看次数: |
2914 次 |
| 最近记录: |