@DateTimeFormat
与 @JsonFormat
的区别
-
@JsonFormat
是 jackson 对 json 数据进行格式化, 包含序列化和反序列化. 只与 json 有关. -
@DateTimeFormat
是 spring 对日期格式的赋值进行格式化, 只包含反序列化. 作用是限制入参格式.
为什么要使用 @DateTimeFormat
限制呢?
- 因为日期的表现形式有很多种, 如果不规定格式, 后端就不知道以何种格式接收, 就好比年月日和日月年.(默认按照UTC日期格式:
"yyyy-MM-dd'T'HH:mm:ss.SSSX"
, 但实测传入"yyyy-MM-d"
也可以接收) 设置@DateTimeFormat
该值之后, 就只能传该格式. - UTC日期格式对于前端极其不友好
在同时设置时 @DateTimeFormat
失效只匹配 @JsonFormat
?
- 接下来就是关键的地方了,
@JsonFormat
只与 json 有关. 所以当我们在处理 post 之类, 带有请求体为 json 的请求时, 在实际处理中 jackson 已经将该值处理了. 并没有通过@DateTimeFormat
所以就会出现失效的问题. @DateTimeFormat
本就对 json 格式无效
结论
-
两者主要根据请求的数据类型来对比
- 请求非 JSON 数据,用
@DateTimeFormat
即可,比如get请求。 - 请求 JSON 数据,用
@ReqeustBody
来转换数据,然后搭配局部注解@JsonFormat
或者全局配置来修改默认的日期解析格式(默认为 UTC 日期格式:"yyyy-MM-dd'T'HH:mm:ss.SSSX"
)
- 请求非 JSON 数据,用
全局配置
- SpringBoot
spring:
# Content-Type 为 application/json, @JsonFormat(优先级高) 或 spring.jackson.date-format
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# Content-Type 为 application/x-www-form-urlencoded(普通表单上传)spring.mvc.date-format(优先级高) 或 @DatetimeFormat
mvc:
format:
date-time: yyyy-MM-dd HH:mm:ss
或 (支持 LocalDateTime
)
- SpringBoot (
JsonFormat
)
@Configuration
public class ContactAppConfig {
private static final String dateFormat = "yyyy-MM-dd";
private static final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> {
builder.simpleDateFormat(dateTimeFormat);
builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
};
}
}
- SpringBoot (
DateTimeFormat
) 官网
@Configuration
public class DateTimeConfig extends WebMvcConfigurationSupport {
@Bean
@Override
public FormattingConversionService mvcConversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);
DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
dateTimeRegistrar.setTimeFormatter(DateTimeFormatter.ofPattern("HH:mm:ss"));
dateTimeRegistrar.registerFormatters(conversionService);
// DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
// dateRegistrar.setFormatter(new DateFormatter("yyyy-MM-dd"));
// dateRegistrar.registerFormatters(conversionService);
return conversionService;
}
}