FastJson是阿里巴巴开源的一款高性能JSON解析和序列化库,凭借其简洁的API设计和不错的性能表现,在国内Java项目中使用率相当高。无论你是刚接触JSON处理的新手,还是想在项目里规范使用FastJson的开发者,这篇文章都值得通读一遍,基本能覆盖日常开发的绝大部分场景。

FastJson基础入门:快速上手环境准备与核心API
使用FastJson前,先在项目中引入依赖。以Maven为例,在pom.xml中加入以下配置即可。需要注意FastJson版本迭代较快,建议使用1.2.83或更高版本,早期版本存在已被披露的反序列化安全漏洞,不要随意使用老旧版本。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>FastJson的入口类是com.alibaba.fastjson.JSON,它提供了最常用的静态方法。最核心的几个方法分别是:toJSONString用于把Java对象序列化成JSON字符串,parseObject用于把JSON字符串反序列化成对象或JSONObject,parseArray用于把JSON数组字符串转换成List或JSONArray。
先看一个最简单的例子,定义一个User类,然后完成序列化和反序列化的完整流程:
public class User {
private Long id;
private String name;
private Integer age;
// 省略getter和setter
}
User user = new User();
user.setId(1L);
user.setName("张三");
user.setAge(25);
// 序列化:对象转JSON字符串
String json = JSON.toJSONString(user);
System.out.println(json); // {"age":25,"id":1,"name":"张三"}
// 反序列化:JSON字符串转对象
User u = JSON.parseObject(json, User.class);
System.out.println(u.getName()); // 张三这里有个细节值得注意:FastJson在反序列化时依赖无参构造器和setter方法。如果你的类只有带参构造器且没有提供无参版本,解析时会抛出异常。这在Lombok重度项目中偶尔会遇到,解决方式是给类补上@NoArgsConstructor注解或者手写一个无参构造器。
JSONObject与JSONArray:不依赖实体类的灵活解析
实际开发中经常遇到结构不固定或者只需要取其中几个字段的JSON数据,这时候为每个结构都建实体类太笨重。FastJson提供了JSONObject和JSONArray两个容器类,可以像操作Map和List一样操作JSON数据。
JSONObject实现了Map接口,JSONArray实现了List接口,所以你可以直接调用getString、getInteger、getLong、getJSONObject等类型安全的方法来取值,避免手动强转:
String json = "{\"code\":200,\"msg\":\"success\",\"data\":{\"name\":\"李四\",\"tags\":[\"vip\",\"new\"]}}";
JSONObject root = JSON.parseObject(json);
Integer code = root.getInteger("code");
String name = root.getJSONObject("data").getString("name");
JSONArray tags = root.getJSONObject("data").getJSONArray("tags");
// 遍历数组
for (int i = 0; i < tags.size(); i++) {
System.out.println(tags.getString(i));
}
// 使用JSONPath提取字段,适合层级较深的场景
String msg = JSONPath.eval(root, "$.msg").toString();对于复杂嵌套结构,JSONPath是一个非常好用的工具,语法类似于XPath,用$.a.b[0].c这样的表达式就能直达目标字段,省去层层判断空指针的麻烦。此外,如果需要把JSON数组直接转成对象列表,可以这样做:
String arrJson = "[{\"id\":1,\"name\":\"a\"},{\"id\":2,\"name\":\"b\"}]";
List<User> users = JSON.parseArray(arrJson, User.class);注解配置与高级用法:定制序列化行为
FastJson通过注解来定制序列化行为,最常用的是@JSONField。它可以修改字段在JSON中的名称、控制序列化和反序列化的顺序、指定日期格式等。对接第三方接口时字段命名经常对不上,这个注解能解决大部分问题。
public class Order {
@JSONField(name = "order_id")
private Long orderId;
@JSONField(name = "create_time", format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JSONField(serialize = false) // 序列化时忽略该字段
private String password;
@JSONField(deserialize = false) // 反序列化时忽略该字段
private String extra;
// 省略getter和setter
}除了注解,toJSONString方法还支持传入SerializerFeature参数来控制全局输出行为。比如默认情况下FastJson会忽略值为null的字段,如果接口要求字段必须输出,可以加上WriteMapNullValue;想让输出格式化便于调试,可以用PrettyFormat。
// 输出null字段并格式化 String json = JSON.toJSONString(order, SerializerFeature.WriteMapNullValue, SerializerFeature.PrettyFormat);
还有一个容易被忽略的特性是循环引用检测。当两个对象互相引用时,FastJson默认会输出$ref引用标记来避免死循环,但很多前端解析库并不认识这个标记,导致数据异常。解决办法是加上SerializerFeature.DisableCircularReferenceDetect关闭循环引用检测,前提是确认数据中不存在真正的循环引用。
常见问题解答与方案选型建议
问题一:反序列化时报错com.alibaba.fastjson.JSONException怎么办?最常见的三种原因:JSON字符串格式非法(比如多了一个逗号)、目标字段类型不匹配(JSON里是字符串但实体类是Integer)、以及缺少无参构造器。建议先把原字符串打印出来用校验工具检查格式,再逐一核对字段类型。
问题二:日期字段序列化后变成了时间戳怎么处理?FastJson默认把Date序列化成毫秒时间戳,如果需要人类可读的格式,在字段上加@JSONField(format = "yyyy-MM-dd HH:mm:ss"),或者序列化时全局指定JSON.toJSONString(obj, "yyyy-MM-dd HH:mm:ss")这种带dateFormat的重载形式。
问题三:FastJson的autoType是什么,为什么频繁爆出漏洞?autoType允许JSON中通过@type字段指定反序列化的目标类,这个特性一旦被恶意利用,攻击者可以实例化任意危险类执行命令。1.2.83版本默认开启了安全模式,只允许白名单内的类。如果你的系统需要反序列化任意类型,务必配合ParserConfig的白名单机制使用,绝不要为了图省事直接放开全部限制。
最后聊聊选型。FastJson的优势是API简洁、上手快、对国内开发者友好;Jackson是Spring Boot默认集成方案,生态兼容性最好;Gson出自Google,胜在稳定轻量、没有历史漏洞包袱。如果你的项目是Spring全家桶且没有特殊性能要求,用Jackson最省心;如果需要处理大量不规则JSON数据且团队已经熟悉FastJson,继续使用新版FastJson完全没问题。工具没有绝对的好坏,关键是理解其特性并在团队内保持统一规范。
FastJsonJava JSON解析JSONObject修改时间:2026-09-05 19:30:48