【Java后端】@DateTimeFormat @JsonFormat 时间格式传参总结
1. 前言
最近在时间Date传参时,没有加注解、前端多种格式都可以接收到数据,从而总结一下其中的原因。
2. 介绍
2.1 无注解
在Spring Boot 2.x中,当前端通过POST请求发送一个时间字符串"2023-06-20 21:04:50"时,后端使用Date类型来接收,并且没有标注任何注解,仍然可以接收到数据的原因是因为Spring Boot默认使用了Jackson库进行JSON序列化和反序列化。
Jackson库内置了一些默认的日期格式:
- ISO-8601日期格式:2023-06-20
- 日期+时间格式:2023-06-20T21:04:50(必须含有中间的T)
- RFC-1123日期格式:Tue, 20 Jun 2023 21:04:50 GMT
- 时间戳:1564454654000
例如:前端传2023-06-19T17:50:08,后端Date接收即使不写注解,也是可以接到的
2.2 有注解
注解:@DateTimeFormat
和@JsonFormat
@DateTimeFormat
注解是Spring框架提供的,用于控制日期类型属性在Spring MVC中的绑定和格式化。它的作用是将请求参数中的日期字符串转换为Date类型,并设置到对应的实体类属性中。适用于请求数据为非JSON数据,不会格式化返回数据@JsonFormat
注解是Jackson库提供的,用于控制日期类型属性在序列化和反序列化时的格式化。它的作用是将Java对象中的日期类型属性格式化为指定格式的字符串,在序列化为JSON字符串时输出。适用于请求数据为JSON数据(尤其有日期数据时),且需在请求方法的参数前加@RequestBody注解,会格式化返回数据
3. 案例
以下结果是通过封装实体进行测试的,FORM表单和JSON的区别在于加不加@RequestBody注解。
3.1 不添加注解
在JSON类型中,使用的是springboot自带的Jackson库进行JSON序列化和反序列化。
在FORM类型中,仅RFC-1123日期格式日期格式才可以成功接到参数。
类型 | 前端传参 | 注解 | 结果 | 返回值 |
JOSN | 2023-06-19 | 无 | √ | 2023-06-19T00:00:00.000+00:00 |
JOSN | 2023-06-19T17:50:08 | 无 | √ | 2023-06-19T17:50:08.000+00:00 |
JOSN | 2023-06-19 17:50:08 | 无 | × | |
JOSN | Tue, 20 Jun 2023 21:04:50 GMT | 无 | √ | 2023-06-20T21:04:50.000+00:00 |
FORM | 2023-06-19 | 无 | × | |
FORM | 2023-06-19T17:50:08 | 无 | × | |
FORM | 2023-06-19 17:50:08 | 无 | × | |
FORM | Tue, 20 Jun 2023 21:04:50 GMT | 无 | √ | 2023-06-20T21:04:50.000+00:00 |
3.2 【JSON方式】仅有@JsonFormat注解
在此种情况下,yyyy-MM-dd
与yyyy-MM-dd HH:mm:ss
的区别可以这样理解:越短相当于限制的越少,兼容性会跟高。
前端传参 | 注解 | 结果 | 返回值 |
2023-06-19 | @JsonFormat(pattern = “yyyy-MM-dd”, timezone = “GMT+8”) | √ | 2023-06-19 |
2023-06-19T17:50:08 | @JsonFormat(pattern = “yyyy-MM-dd”, timezone = “GMT+8”) | √ | 2023-06-19 |
2023-06-19 17:50:08 | @JsonFormat(pattern = “yyyy-MM-dd”, timezone = “GMT+8”) | √ | 2023-06-19 |
2023-06-19 | @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”) | × | |
2023-06-19T17:50:08 | @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”) | × | |
2023-06-19 17:50:08 | @JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”) | √ | 2023-06-19 17:50:08 |
3.4 【Form表单方式】仅有@DateTimeFormat注解
在此种情况下,与上述一样:越短相当于限制的越少,兼容性会跟高。
前端传参 | 注解 | 结果 | 返回值 |
2023-06-19 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | √ | 2023-06-18T16:00:00.000+00:00 |
2023-06-19T17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | √ | 2023-06-18T16:00:00.000+00:00 |
2023-06-19 17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | √ | 2023-06-18T16:00:00.000+00:00 |
2023-06-19 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | × | |
2023-06-19T17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | × | |
2023-06-19 17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | √ | 2023-06-19T09:50:08.000+00:00 |
4. 小结
@JsonFormat注解和@DateTimeFormat注解分别在JSON、FORM类中请求成功的案例是一样的,区别在于@JsonFormat会对返回数据进行格式化处理。
5 其他情况
5.1 【JSON方式】仅有@DateTimeFormat注解
与3.2进行对比,请求成功情况正好互补
前端传参 | 注解 | 结果 | 返回值 |
2023-06-19 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | √ | 2023-06-19T00:00:00.000+00:00 |
2023-06-19T17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | √ | 2023-06-19T17:50:08.000+00:00 |
2023-06-19 17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | × | |
2023-06-19 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | √ | 2023-06-19T00:00:00.000+00:00 |
2023-06-19T17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | √ | 2023-06-19T17:50:08.000+00:00 |
2023-06-19 17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | × |
5.2【FORM表单方式】仅有@JsonFormat注解
在这种情况,均不能请求成功。
前端传参 | 注解 | 结果 | 返回值 |
2023-06-19 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | × | |
2023-06-19T17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | × | |
2023-06-19 17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd”) | × | |
2023-06-19 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | × | |
2023-06-19T17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | × | |
2023-06-19 17:50:08 | @DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”) | × |
6. 总结
之前有个说法:@DateTimeFormat:管理输入数据格式
@JsonFormat:管理返回结果格式
经测试这个说法不完全对,@JsonFormat确实管理返回结果格式,但是输入数据格式是由两个注解相辅相成进行处理的。
建议使用时,两个注解写一样的格式化类型,兼容性如下图(两个注解都添加):
类型 | 前端传参 | 注解 | 结果 | 返回值 |
JSON | 2023-06-19 | yyyy-MM-dd | √ | 2023-06-19 |
JSON | 2023-06-19T17:50:08 | yyyy-MM-dd | √ | 2023-06-19 |
JSON | 2023-06-19 17:50:08 | yyyy-MM-dd | √ | 2023-06-19 |
JSON | 2023-06-19 | yyyy-MM-dd HH:mm:ss | × | |
JSON | 2023-06-19T17:50:08 | yyyy-MM-dd HH:mm:ss | × | |
JSON | 2023-06-19 17:50:08 | yyyy-MM-dd HH:mm:ss | √ | 2023-06-19 17:50:08 |
FORM | 2023-06-19 | yyyy-MM-dd | √ | 2023-06-19 |
FORM | 2023-06-19T17:50:08 | yyyy-MM-dd | √ | 2023-06-19 |
FORM | 2023-06-19 17:50:08 | yyyy-MM-dd | √ | 2023-06-19 |
FORM | 2023-06-19 | yyyy-MM-dd HH:mm:ss | × | |
FORM | 2023-06-19T17:50:08 | yyyy-MM-dd HH:mm:ss | × | |
FORM | 2023-06-19 17:50:08 | yyyy-MM-dd HH:mm:ss | √ | 2023-06-19 17:50:08 |