Java 8
Spring Boot 2.7.3
jackson 2.13.3
--
ben发布于博客园
0、前言
开发过程中遇到问题:
前端调用接口得到的时间对象(java.util.Date)总是存在这样那样的问题。
调查后发现,可以使用 @JsonFormat注解(来自jackson依赖包)解决相关问题。
ben发布于博客园
新建spring boot项目,引入:
spring-boot-starter-web
lombok
其中包含了 jackson依赖包:
注,参考资料#1 一定要看看。 ben发布于博客园
1、使用@JsonFormat处理java.util.Date对象
建一个接口获取当前时间(各种Date对象):
AppV2Controller
@RestController
@RequestMapping(value = {"/api/app/v2"})
@RequiredArgsConstructor
@Slf4j
public class AppV2Controller {
@GetMapping(value = "/get1")
public RespVO get1() {
RespVO vo = new RespVO();
Date now = new Date();
// 时间
vo.setTime(now);
vo.setTimeFmt1(now);
vo.setTimeFmt2(now);
vo.setTimeFmt3(now);
vo.setTimeServerLocal(now);
vo.setTimeServerLocal2(now);
vo.setTimeServerLocal3(now);
// 数字
vo.setIntMax(Integer.MAX_VALUE);
vo.setLongMax(Long.MAX_VALUE);
vo.setIntMaxStr(Integer.MAX_VALUE);
vo.setLongMaxStr(Long.MAX_VALUE);
return vo;
}
}
RespVO
RespVO类
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@Data
public class RespVO {
// 默认格式
private Date time;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date timeFmt1;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
private Date timeFmt2;
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
private Date timeFmt3;
// 有效:值可以根据 TimeZone.getAvailableIDs() 的结果进一步获取
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date timeServerLocal;
// 有效,同上
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date timeServerLocal2;
// 无效
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC+8")
private Date timeServerLocal3;
private Integer intMax;
private Long longMax;
// Integer 序列化为字符串
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Integer intMaxStr;
// Long 序列化为字符串
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long longMaxStr;
}
启动后访问接口(Postman):/api/app/v2/get1,得到下面的响应:ben发布于博客园
{
"time": "2022-09-21T11:41:11.079+00:00",
"timeFmt1": "2022-09-21 11:41:11",
"timeFmt2": "2022-09-21 11:41:11.079",
"timeFmt3": 1663760471079,
"timeServerLocal": "2022-09-21 19:41:11",
"timeServerLocal2": "2022-09-21 19:41:11",
"timeServerLocal3": "2022-09-21 11:41:11",
"intMax": 2147483647,
"longMax": 9223372036854775807,
"intMaxStr": "2147483647",
"longMaxStr": "9223372036854775807"
}
默认返回的 time 是 UTC时间,格式有些长;
timeFmt1 、timeFmt2 也是UTC时间,后者多了毫秒数;
timeFmt3 返回 时间戳,使用了shape参数——Date对象转换为数字,推荐使用这种方式,前端可以直接建立 JavaScript 的Date对象——如果需要进一步处理;
timeServerLocal、timeServerLocal2 返回了服务器本地时间,因为使用了timezone,不过,推荐使用 timeServerLocal2 这种格式的格式的 timezone属性——直观;
timeServerLocal3 的 timezone 配置失败,但未发生错误,返回了 UTC时间。ben发布于博客园
对于之后的Integer、Long型对象转换,默认是数字,设置 @JsonFormat 的 shapte属性为 JsonFormat.Shape.STRING 可以将其转换为 字符串。
2、转换Date对象:spring.jackson.date-format配置
S.B.项目的默认 Date对象 格式 很长,如,"2022-09-21T11:41:11.079+00:00"。
可以使用 参数 spring.jackson.date-format 进行配置,如下:
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss.SSS
配置后,获取的默认时间对象格式出现了变化:
"time": "2022-09-21 11:10:45.434"
没有默认的那么长了,和配置一致。ben发布于博客园
默认返回的是UTC时间,还可以使用 spring.jackson.time-zone 设置默认返回的时间字符串的时区。
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss.SSS
time-zone: GMT+8
调用接口后返回:
{
"time": "2022-09-21 19:15:06.022",
"timeFmt1": "2022-09-21 19:15:06",
"timeFmt2": "2022-09-21 19:15:06.022",
"timeFmt3": 1663758906000,
"timeServerLocal": "2022-09-21 19:15:06",
"timeServerLocal2": "2022-09-21 19:15:06",
"timeServerLocal3": "2022-09-21 11:15:06",
...
除了 timezone属性值 错误的 timeServerLocal3,其它的 时间字符串 都是 服务器时间格式化后的字符串(GMT+8)。ben发布于博客园
3、小结
时间对象转换为字符串,式样繁多,在和前端交互时,沟通比较复杂。
如前文所说,直接使用 时间戳方式 在前后端之间传递 时间数据比较好,可以避免做各种转换——UTC时间 和 本地时间 的转换。ben发布于博客园
@JsonFormat 来自 Jackson包,用来做 JSON数据 序列化/反序列化,Spring框架默认使用它。看完 参考资料#1 ,还可以配置其它依赖包来做序列化,比如,fastjson, gson。
在 Spring Boot 官方文档中,介绍了“Custom JSON Serializers and Deserializers”,可以看看。
启动 Spring Boot 项目时,可以看到一些 包含 jackson 字样的 Bean:
参考资料
1、Jackson使用详解
https://juejin.cn/post/6844904166809157639
三分恶 发布于 2020年05月23日 23:27
对jackson介绍的很详细。
2、jackSon中@JsonFormat注解使用详解
https://blog.csdn.net/weixin_44130081/article/details/89641301
3、springboot之jackson的两种配置方式
https://www.cnblogs.com/liaojie970/p/9396334.html
4、
ben发布于博客园
标签:JsonFormat,java,09,vo,util,2022,Date,jackson From: https://www.cnblogs.com/luo630/p/16715892.html