Jackson
Jackson介绍
Jackson 是一套高性能、功能全面的 Java JSON 解析 / 生成库,也是 Spring Boot 默认的 JSON 处理库。
Jackson 的核心优势:
速度快:底层基于流式 API,内存占用低;
功能全:支持对象与 JSON 互转、复杂类型(泛型、集合、嵌套对象)、自定义序列化 / 反序列化;
可定制:通过注解或自定义处理器灵活控制 JSON 转换规则;
兼容性好:支持 JDK 各种数据类型。
Jackson 采用模块化设计,最核心的三个模块如下:
jackson-core:底层核心模块,提供 JSON 的流式解析(JsonParser)和生成(JsonGenerator);
jackson-annotations:注解模块,提供序列化 / 反序列化的定制注解;
jackson-databind:数据绑定核心模块,依赖前两个模块,提供 ObjectMapper 实现对象与 JSON 互转。
Spring Boot 的 spring-boot-starter-web(Web 开发核心依赖)已经内置了 Jackson 的核心依赖(jackson-databind、jackson-core、jackson-annotations),只需要引入 web starter 即可直接使用 Jackson,无需额外声明。
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 无需指定版本,Spring Boot父工程已统一管理 -->
</dependency>
属性
Spring Boot 为了简化 Jackson 的日期时间处理配置提供了外部化配置项,无需手动编写代码修改 Jackson 核心类 ObjectMapper 的日期处理规则,直接在配置文件中设置就能生效。
- spring.jackson.time-zone: GMT+8:指定时区
设置 Jackson 处理日期时间时使用的时区,GMT+8 是东八区(北京时间 / 中国标准时间);
Jackson 默认使用 UTC 时区(世界协调时间,比北京时间晚 8 小时),如果不配置这个参数,会出现接口返回的时间比实际时间少 8 小时问题。 - spring.jackson.date-format: yyyy-MM-dd HH:mm:ss:指定日期格式
设置 Jackson 序列化日期时间类型时的统一字符串格式,同时也支持反序列化;
若移除这个配置,Jackson 就会回到默认规则,输出 ISO 8601 格式的字符串。
演示结果如下:
数据库中的数据为:2021-01-19 11:00:02
Java 后端接收到的数据为:Tue Jan 19 11:00:02 CST 2021
前端展示的数据为:
未配置时区和日期格式时:2021-01-19T03:00:02.000+0000
仅未配置时区时:2021-01-19 03:00:02
仅未配置日期格式时:2021-01-19T11:00:02.000+0800
配置 GMT+8 和 yyyy-MM-dd HH:mm:ss 后:2021-01-19 11:00:02
具体解释如下:
2021-01-19T11:00:02.000+0800 是 ISO 8601 标准时间格式,也是 Jackson 处理 Java 8 时间类型时的默认序列化格式:
T:是 ISO 8601 标准中日期和时间的分隔符;
2021-01-19:日期部分(年 - 月 - 日);
11:00:02.000:时间部分(时:分: 秒。毫秒);
+0800:时区偏移(东八区,即 GMT+8)。
date-format 的作用是覆盖默认格式
date-format: yyyy-MM-dd HH:mm:ss 本质是强制 Jackson 放弃默认的 ISO 8601 格式,改用指定的自定义格式,一旦移除这个配置,Jackson 就会回到默认规则,输出 ISO 8601 格式的字符串。
Jackson 对时间类型的序列化规则差异
- 对于 java.util.Date:Jackson 核心模块内置了对 Date 类型的序列化器,默认会把 Date 序列化成时间戳(数字) 或格式化后的字符串,前端能直接识别并显示;
- 对于 LocalDateTime:LocalDateTime 是 Java 8 新增的时间 API,Jackson 核心模块没有内置对它的序列化支持;
Spring Boot 虽然默认集成了 Jackson,但如果没有引入专门处理 Java 8 时间类型的模块,也会导致 LocalDateTime 序列化异常,若需要引入 Jackson 处理 Java 8 时间类型,需要添加 jackson-datatype-jsr310 模块依赖;
此外,默认情况下,Jackson 会把 LocalDateTime 序列化成一个嵌套的复杂对象(包含 year、month、dayOfMonth 等子字段),如果前端没有专门处理这种嵌套结构,就会显示 null、[object Object] 或直接不显示。
xml
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.17.1</version>
</dependency>
若项目使用到了逆向工程,需要注意的是:
MyBatis Generator(MBG)逆向工程工具设计较早,默认适配 JDK 7 及更低版本,数据库 timestamp 字段默认不映射为 LocalDateTime,而是映射为 java.util.Date;
MyBatis-Plus (新版,如 3.5+)代码生成器默认适配 Java 8+,数据库 timestamp/datetime 字段都会默认生成 LocalDateTime 类型(替代传统的 Date)。