FastJson 完全学习指南(初学者从零入门)
一、JSON 数据格式基础
1.1 什么是 JSON?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于 ECMAScript 规范,采用文本格式存储和表示数据。其核心特点是:
简洁清晰:层次结构明确,易于人类阅读和编写
跨语言:独立于编程语言,几乎所有编程语言都支持 JSON 解析
高效传输:文本格式体积小,适合网络传输
目前,JSON 已成为前后端数据交互、接口通信的主流格式。
1.2 JSON 基本格式
1.2.1 JSON 键值对规则
键必须是字符串,且必须用双引号 "" 包裹(单引号不合法)
值可以是以下类型:字符串、数字、布尔值(true/false)、null、数组、对象
键值对之间用逗号 , 分隔(最后一个键值对后不能有逗号)
1.2.2 JSON 数组(Array)
由中括号 [] 包裹,元素之间用逗号分隔,元素类型可以是任意 JSON 支持的类型。
示例:
// 数组元素为字符串
["张三", "李四", "王五"]
// 数组元素为混合类型
[18, "张三", true, null, {
"score": 90}]
访问方式(以 JavaScript 为例):
var arr = [18, "张三", true];
console.log(arr[0]); // 输出:18(访问第一个元素)
console.log(arr.length); // 输出:3(数组长度)
1.2.3 JSON 对象(Object)
由大括号 {} 包裹,采用键值对 key:value 形式存储。
示例:
{
"id": 1,
"name": "张三",
"age": 20,
"isStudent": true,
"address": null
}
访问方式(以 JavaScript 为例):
var obj = {
"id": 1, "name": "张三"};
console.log(obj.name); // 输出:张三(通过键访问值)
console.log(obj["age"]); // 输出:undefined(键不存在时)
1.2.4 嵌套格式(数组与对象混合)
JSON 支持数组和对象相互嵌套,形成复杂结构。
示例 1:数组中的元素是对象
[
{
"id": 1, "name": "张三"},
{
"id": 2, "name": "李四"}
]
访问方式:arr[0].name → 输出 "张三"
示例 2:对象中的值是数组
{
"className": "高三(1)班",
"students": [
{
"id": 1, "name": "张三"},
{
"id": 2, "name": "李四"}
]
}
访问方式:obj.students[1].id → 输出 2
示例 3:多层嵌套
{
"school": "第一中学",
"grades": [
{
"gradeName": "高三",
"classes": [
{
"className": "一班", "studentCount": 50},
{
"className": "二班", "studentCount": 48}
]
}
]
}
访问方式:obj.grades[0].classes[0].className → 输出 "一班"
二、FastJson 介绍
2.1 什么是 FastJson?
FastJson 是阿里巴巴开源的 JSON 解析库,主要功能是:
将 Java 对象序列化为 JSON 字符串(Java → JSON)
将 JSON 字符串反序列化为 Java 对象(JSON → Java)
2.2 FastJson 的优势
速度快:性能远超其他 Java JSON 库(如 Jackson、Gson)
功能全:支持泛型、日期格式化、枚举、流处理等
使用简单:API 简洁,一行代码即可完成序列化/反序列化
兼容性好:广泛应用于阿里巴巴内部及业界,支持各种复杂场景
2.3 环境搭建(引入依赖)
Maven 项目
在 pom.xml 中添加依赖:
Gradle 项目
在 build.gradle 中添加依赖:
implementation 'com.alibaba:fastjson:1.2.83'
三、FastJson 核心 API 详解
3.1 序列化(Java → JSON)
序列化是将 Java 对象转换为 JSON 字符串的过程,核心方法:JSON.toJSONString(Object obj)
3.1.1 序列化 Java 对象
步骤:
定义 Java 实体类(如 Student)
创建对象并赋值
调用 JSON.toJSONString() 方法
示例:
// 1. 定义实体类
import lombok.Data; // 使用 lombok 简化 getter/setter
@Data
public class Student {
private Integer id;
private String name;
private Integer age;
private String address;
}
// 2. 序列化示例
public class FastJsonDemo {
public static void main(String[] args) {
// 创建对象
Student student = new Student();
student.setId(1);
student.setName("张三");
student.setAge(20);
student.setAddress("北京市");
// 序列化
String jsonString = JSON.toJSONString(student);
System.out.println(jsonString);
// 输出:{"address":"北京市","age":20,"id":1,"name":"张三"}
}
}
3.1.2 序列化 List 集合
示例:
public class FastJsonDemo {
public static void main(String[] args) {
// 创建多个对象
Student s1 = new Student();
s1.setId(1);
s1.setName("张三");
s1.setAge(20);
Student s2 = new Student();
s2.setId(2);
s2.setName("李四");
s2.setAge(21);
// 存入 List
List
studentList.add(s1);
studentList.add(s2);
// 序列化 List
String jsonString = JSON.toJSONString(studentList);
System.out.println(jsonString);
// 输出:[{"age":20,"id":1,"name":"张三"},{"age":21,"id":2,"name":"李四"}]
}
}
3.1.3 序列化 Map 集合
示例:
public class FastJsonDemo {
public static void main(String[] args) {
Student s1 = new Student();
s1.setId(1);
s1.setName("张三");
Student s2 = new Student();
s2.setId(2);
s2.setName("李四");
// 创建 Map
Map
studentMap.put("s1", s1);
studentMap.put("s2", s2);
// 序列化 Map
String jsonString = JSON.toJSONString(studentMap);
System.out.println(jsonString);
// 输出:{"s1":{"id":1,"name":"张三"},"s2":{"id":2,"name":"李四"}}
}
}
3.2 反序列化(JSON → Java)
反序列化是将 JSON 字符串转换为 Java 对象的过程,核心方法:
转换为对象:JSON.parseObject(String json, Class
转换为 List:JSON.parseArray(String json, Class
转换为 Map:JSON.parseObject(String json, TypeReference
3.2.1 反序列化为 Java 对象
示例:
public class FastJsonDemo {
public static void main(String[] args) {
// JSON 字符串
String jsonString = "{\"address\":\"北京市\",\"age\":20,\"id\":1,\"name\":\"张三\"}";
// 反序列化
Student student = JSON.parseObject(jsonString, Student.class);
System.out.println(student.getName()); // 输出:张三
System.out.println(student.getAge()); // 输出:20
}
}
3.2.2 反序列化为 List 集合
示例:
public class FastJsonDemo {
public static void main(String[] args) {
// JSON 数组字符串
String jsonString = "[{\"age\":20,\"id\":1,\"name\":\"张三\"},{\"age\":21,\"id\":2,\"name\":\"李四\"}]";
// 反序列化为 List
List
for (Student s : studentList) {
System.out.println(s.getName());
}
// 输出:
// 张三
// 李四
}
}
3.2.3 反序列化为 Map 集合
示例:
public class FastJsonDemo {
public static void main(String[] args) {
// JSON 字符串(键为字符串,值为对象)
String jsonString = "{\"s1\":{\"id\":1,\"name\":\"张三\"},\"s2\":{\"id\":2,\"name\":\"李四\"}}";
// 反序列化为 Map(使用 TypeReference 处理泛型)
Map
jsonString,
new TypeReference
}
);
// 遍历 Map
for (Map.Entry
System.out.println(entry.getKey() + " → " + entry.getValue().getName());
}
// 输出:
// s1 → 张三
// s2 → 李四
}
}
四、SerializerFeature 序列化特性
SerializerFeature 是 FastJson 提供的枚举类,用于定制序列化行为(如处理 null、格式化日期等)。
常用特性及示例
特性常量
作用描述
WriteMapNullValue
序列化 null 字段(默认不序列化 null)
WriteNullStringAsEmpty
null 字符串字段序列化为空字符串 ""
WriteNullNumberAsZero
null 数字字段序列化为 0
WriteNullBooleanAsFalse
null 布尔字段序列化为 false
WriteDateUseDateFormat
格式化日期(默认毫秒数,可自定义格式)
PrettyFormat
格式化输出(带缩进和换行,便于阅读)
示例 1:序列化 null 字段
public class FastJsonDemo {
public static void main(String[] args) {
Student student = new Student();
student.setId(1);
student.setName("张三");
// age 和 address 未赋值(为 null)
// 默认序列化(不包含 null 字段)
String defaultJson = JSON.toJSONString(student);
System.out.println("默认:" + defaultJson);
// 输出:{"id":1,"name":"张三"}
// 序列化 null 字段
String withNullJson = JSON.toJSONString(student, SerializerFeature.WriteMapNullValue);
System.out.println("包含 null:" + withNullJson);
// 输出:{"address":null,"age":null,"id":1,"name":"张三"}
}
}
示例 2:处理 null 字段为默认值
public class FastJsonDemo {
public static void main(String[] args) {
Student student = new Student();
student.setId(1);
// name、age、address 为 null
// null 字符串→"",null 数字→0
String json = JSON.toJSONString(
student,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullNumberAsZero
);
System.out.println(json);
// 输出:{"address":"","age":0,"id":1,"name":""}
}
}
示例 3:日期格式化
import java.util.Date;
@Data
public class User {
private String name;
private Date birthday; // 日期字段
}
public class FastJsonDemo {
public static void main(String[] args) {
User user = new User();
user.setName("张三");
user.setBirthday(new Date()); // 当前时间
// 默认日期格式(毫秒数)
String defaultJson = JSON.toJSONString(user);
System.out.println("默认日期:" + defaultJson);
// 输出:{"birthday":1695670000000,"name":"张三"}
// 格式化日期为 "yyyy-MM-dd HH:mm:ss"
String formatJson = JSON.toJSONString(
user,
SerializerFeature.WriteDateUseDateFormat
);
System.out.println("格式化日期:" + formatJson);
// 输出:{"birthday":"2023-09-25 10:20:30","name":"张三"}
}
}
示例 4:格式化输出(PrettyFormat)
public class FastJsonDemo {
public static void main(String[] args) {
Student student = new Student();
student.setId(1);
student.setName("张三");
student.setAge(20);
// 格式化输出(带缩进)
String prettyJson = JSON.toJSONString(student, SerializerFeature.PrettyFormat);
System.out.println(prettyJson);
// 输出:
// {
// "age":20,
// "id":1,
// "name":"张三"
// }
}
}
五、FastJson 注解详解
FastJson 提供了注解用于定制类或字段的序列化/反序列化规则,常用注解:@JSONField(作用于字段/方法)和 @JSONType(作用于类)。
5.1 @JSONField 注解
常用属性:
属性名
作用描述
name
指定序列化后的字段名(解决命名不一致问题)
format
字段格式化(如日期格式)
serialize
是否序列化该字段(true/false)
deserialize
是否反序列化该字段(true/false)
ordinal
序列化时的字段顺序(值越小越靠前)
示例:
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;
@Data
public class User {
// 序列化后字段名为 "userId"
@JSONField(name = "userId")
private Integer id;
// 不序列化该字段
@JSONField(serialize = false)
private String password;
// 日期格式化
@JSONField(format = "yyyy年MM月dd日")
private Date birthday;
// 序列化顺序(1 比 2 靠前)
@JSONField(ordinal = 1)
private String name;
@JSONField(ordinal = 2)
private Integer age;
}
public class FastJsonDemo {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(20);
user.setPassword("123456"); // 不序列化
user.setBirthday(new Date());
String json = JSON.toJSONString(user);
System.out.println(json);
// 输出:{"userId":1,"name":"张三","age":20,"birthday":"2023年09月25日"}
}
}
5.2 @JSONType 注解
作用于类上,对整个类的序列化/反序列化进行全局配置。
常用属性:
属性名
作用描述
includes
指定需要序列化的字段(仅这些字段被序列化)
orders
指定字段序列化顺序(数组形式,按顺序排列)
serializeFeatures
全局序列化特性(如默认格式化日期)
示例:
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.serializer.SerializerFeature;
// 仅序列化 id 和 name,且按 [name, id] 顺序,默认格式化日期
@JSONType(
includes = {
"id", "name"},
orders = {
"name", "id"},
serializeFeatures = SerializerFeature.WriteDateUseDateFormat
)
@Data
public class User {
private Integer id;
private String name;
private Integer age; // 不被序列化(未在 includes 中)
private Date birthday;
}
public class FastJsonDemo {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(20); // 不序列化
user.setBirthday(new Date());
String json = JSON.toJSONString(user);
System.out.println(json);
// 输出:{"name":"张三","id":1,"birthday":"2023-09-25 10:30:40"}
}
}
六、Spring Boot 集成 FastJson
Spring Boot 默认使用 Jackson 作为 JSON 解析器,如需替换为 FastJson,步骤如下:
6.1 环境准备
创建 Spring Boot 项目(需引入 spring-boot-starter-web 依赖)
在 pom.xml 中添加 FastJson 依赖(同 2.3 节)
6.2 配置 FastJson 为默认解析器
通过配置 HttpMessageConverter 替换默认解析器。
步骤:
创建配置类(标注 @Configuration)
实现 WebMvcConfigurer 接口
重写 configureMessageConverters 方法,注册 FastJson 消息转换器
示例代码:
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class FastJsonConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List
// 1. 创建 FastJson 消息转换器
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
// 2. 配置 FastJson 特性
FastJsonConfig fastJsonConfig = new FastJsonConfig();
// 序列化 null 字段
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
// 格式化日期
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat);
// 格式化输出(开发环境用,生产环境建议关闭)
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
// 设置字符集
fastJsonConfig.setCharset(StandardCharsets.UTF_8);
// 3. 配置支持的媒体类型(解决中文乱码)
List
mediaTypes.add(MediaType.APPLICATION_JSON);
mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
converter.setSupportedMediaTypes(mediaTypes);
// 4. 将配置添加到转换器
converter.setFastJsonConfig(fastJsonConfig);
// 5. 将转换器添加到容器(放在首位,优先使用)
converters.add(0, converter);
}
}
6.3 测试集成效果
创建一个 Controller 测试接口返回 JSON 格式:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
public class TestController {
@GetMapping("/user")
public User getUser() {
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(null); // 测试 null 字段序列化
user.setBirthday(new Date()); // 测试日期格式化
return user;
}
}
启动项目后访问 http://localhost:8080/user,返回结果:
{
"userId": 1,
"name": "张三",
"age": null,
"birthday": "2023-09-25 11:00:00"
}
(结果说明:FastJson 已生效,null 字段被序列化,日期已格式化)
七、常见问题与解决方案
问题:序列化后字段名与 Java 类字段名不一致?解决:使用 @JSONField(name = "目标字段名") 注解指定。
问题:null 字段未被序列化?解决:添加特性 SerializerFeature.WriteMapNullValue。
问题:日期字段显示为毫秒数而非字符串?解决:添加特性 SerializerFeature.WriteDateUseDateFormat 或使用 @JSONField(format = "格式")。
问题:反序列化时提示“无参构造函数不存在”?解决:确保 Java 类有默认无参构造函数(Lombok 的 @Data 会自动生成)。
问题:Spring Boot 集成后中文乱码?解决:在配置消息转换器时指定 UTF-8 字符集(如 6.2 节示例)。
通过本文档,初学者可从零掌握 FastJson 的核心用法,包括 JSON 基础、序列化/反序列化、特性定制、注解使用及 Spring Boot 集成,满足日常开发中的 JSON 处理需求。