当前位置: 首页 > news >正文

替换 FastJSON:推荐 Jackson 及详细用法指南(含工具类 + 替换方案)

文章目录

  • 一、推荐替代库:Jackson
    • 1、市面上主流JSON 解析库
    • 2、为什么选择 Jackson?
  • 二、Maven 依赖(Jackson)
  • 三、Jackson 常用用法详解
    • 1.Java 对象转 JSON 字符串
    • 2.JSON 字符串转 Java 对象
    • 3.将 JSON 字符串转为 JSON 对象(JsonNode vs ObjectNode)
      • (1)JsonNode 与 ObjectNode 的区别
      • (2)将 JSON 字符串转为 JsonNode(类似 FastJSON 的 parseObject)
      • (3)常用 JsonNode 方法总结
      • (4)创建新的 JSON 对象(使用 ObjectNode)
      • (5)FastJSON 与 Jackson 对应写法对照表
      • (6)总结
    • 4.List 转 JSON 数组
    • 4.Map 转 JSON
    • 5.自定义日期格式
    • 6.忽略空字段(NULL 或 EMPTY)
  • 四、封装 Jackson 工具类(带注释)
  • 五、现有 FastJSON 调用方式一键替换成 Jackson 的写法
  • 六、替换步骤建议
  • 七、补充建议
  • 八、不同项目选择json库总结

FastJSON 曾经是 Java 领域最流行的 JSON 序列化/反序列化库之一,但由于其历史安全问题频发、维护不积极等问题,越来越多公司开始禁用 FastJSON,并转向更稳定、安全、标准的替代库。

本文重点介绍推荐替代 FastJSON 的首选库 —— Jackson,并提供完整的使用示例、封装工具类以及从 FastJSON 迁移至 Jackson 的建议。


一、推荐替代库:Jackson

1、市面上主流JSON 解析库

以下是几个主流的 Java JSON 解析库,适合企业级项目替换使用:

名称优点缺点推荐指数
Jackson性能好、功能全、社区活跃、Spring Boot 默认使用配置稍复杂,学习曲线略高⭐⭐⭐⭐⭐
GsonGoogle 出品,简单易用,API 友好性能略逊于 Jackson,不支持流式解析大文件⭐⭐⭐⭐
fastjson2(升级版)FastJSON 官方新版本,修复部分问题社区信任度下降,仍有兼容性/安全性顾虑⭐⭐
moshi简洁现代,适合 Kotlin 和 Android功能较弱,不如 Jackson 强大⭐⭐⭐
Yasson / JSON-BJava EE 标准 JSON 绑定实现使用较少,文档不多⭐⭐

2、为什么选择 Jackson?

特性描述
性能优秀支持流式解析,处理大文件效率高
社区活跃官方维护频繁,文档丰富
Spring Boot 默认集成几乎所有现代 Spring 项目都基于它
安全性更高不像 FastJSON 存在自动类型转换等潜在风险

二、Maven 依赖(Jackson)

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.16.1</version>
</dependency>

⚠️ 注意:jackson-databind 包含了 coreannotations,一般只需引入此依赖即可。


三、Jackson 常用用法详解

1.Java 对象转 JSON 字符串

	//Java 对象转 JSON 字符串@Testpublic void test1() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();User user = new User("admin", "若依", 1L);String json = mapper.writeValueAsString(user);System.out.println(json);// 输出: {"username":"admin","nickName":"若依","userId":1}}

2.JSON 字符串转 Java 对象

//JSON 字符串转 Java 对象@Testpublic void test2() throws JsonProcessingException {String json = "{\"username\":\"admin\",\"nickName\":\"若依\",\"userId\":1}";ObjectMapper mapper = new ObjectMapper();User user = mapper.readValue(json, User.class);System.out.println(user.getUsername()); // admin}

3.将 JSON 字符串转为 JSON 对象(JsonNode vs ObjectNode)

在使用 FastJSON 时,我们经常使用如下方式将字符串解析为 JSON 对象:

JSONObject jsonObject = JSON.parseObject(jsonString);

而在 Jackson 中,并没有 JSONObject 这个类,取而代之的是 JsonNodeObjectNode。理解这两个类的区别和使用方法,对于从 FastJSON 迁移到 Jackson 非常重要。


(1)JsonNode 与 ObjectNode 的区别

类名类型特点
JsonNode只读对象是 Jackson 提供的通用 JSON 节点抽象类,可以表示任意 JSON 值(对象、数组、字符串等)
ObjectNode可写对象JsonNode 的子类,用于构建或修改 JSON 对象,支持添加字段、嵌套结构等

✅ 简单来说:

  • 如果你只是想解析并读取 JSON 数据,使用 JsonNode
  • 如果你想创建或修改 JSON 内容,使用 ObjectNode

(2)将 JSON 字符串转为 JsonNode(类似 FastJSON 的 parseObject)

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;public class JsonNodeExample {public static void main(String[] args) throws Exception {String jsonStr = "{\n" +"  \"username\": \"admin\",\n" +"  \"userId\": 1,\n" +"  \"dept\": {\n" +"    \"deptId\": 103,\n" +"    \"deptName\": \"研发部门\"\n" +"  },\n" +"  \"roles\": [\n" +"    {\"roleId\": 1, \"roleName\": \"超级管理员\"},\n" +"    {\"roleId\": 2, \"roleName\": \"普通用户\"}\n" +"  ]\n" +"}";ObjectMapper mapper = new ObjectMapper();JsonNode rootNode = mapper.readTree(jsonStr);// 获取基本字段String username = rootNode.get("username").asText();int userId = rootNode.get("userId").asInt();// 获取嵌套对象JsonNode deptNode = rootNode.get("dept");String deptName = deptNode.get("deptName").asText();// 获取数组元素JsonNode rolesNode = rootNode.get("roles");for (JsonNode role : rolesNode) {int roleId = role.get("roleId").asInt();String roleName = role.get("roleName").asText();System.out.println("Role ID: " + roleId + ", Name: " + roleName);}}
}

(3)常用 JsonNode 方法总结

方法说明
get("field")获取指定字段的子节点(返回类型为 JsonNode
has("field")判断是否存在该字段
isValueNode()是否是值节点(如字符串、数字等)
isObject()是否是对象节点
isArray()是否是数组节点
isNull()是否为 null
asText()转为字符串
asInt() / asDouble() / asBoolean()转为基础类型
size()获取数组或对象中字段数量
elements()获取对象中所有字段的迭代器
iterator()获取数组中所有元素的迭代器
fieldNames()获取对象的所有字段名(Iterator)

(4)创建新的 JSON 对象(使用 ObjectNode)

如果你需要构造一个新的 JSON 对象,而不是仅仅读取已有的 JSON,可以使用 ObjectNode

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;public class CreateJsonExample {public static void main(String[] args) {ObjectMapper mapper = new ObjectMapper();ObjectNode userNode = mapper.createObjectNode();userNode.put("username", "admin");userNode.put("userId", 1);userNode.put("status", true);// 添加嵌套对象ObjectNode deptNode = mapper.createObjectNode();deptNode.put("deptId", 103);deptNode.put("deptName", "研发部门");userNode.set("dept", deptNode);// 输出 JSON 字符串System.out.println(userNode.toPrettyString());}
}

输出结果:

{"username" : "admin","userId" : 1,"status" : true,"dept" : {"deptId" : 103,"deptName" : "研发部门"}
}

(5)FastJSON 与 Jackson 对应写法对照表

FastJSON 写法Jackson 替代写法
JSONObject jsonObject = JSON.parseObject(jsonString);JsonNode jsonNode = objectMapper.readTree(jsonString);
String name = jsonObject.getString("name");String name = jsonNode.get("name").asText();
Integer age = jsonObject.getInteger("age");int age = jsonNode.get("age").asInt();
JSONObject dept = jsonObject.getJSONObject("dept");JsonNode dept = jsonNode.get("dept");
JSONArray roles = jsonObject.getJSONArray("roles");JsonNode roles = jsonNode.get("roles");
jsonObject.containsKey("key")jsonNode.has("key")
new JSONObject()ObjectNode objectNode = objectMapper.createObjectNode();
jsonObject.put("key", value)objectNode.put("key", value);

(6)总结

功能推荐使用类
解析 JSON 字符串并读取字段JsonNode
构建/修改 JSON 对象ObjectNode
获取字段值.get("field").asText()
判断字段是否存在.has("field")
快速遍历对象字段.fieldNames() + 循环
快速遍历数组for (JsonNode node : arrayNode)

4.List 转 JSON 数组

	@Testpublic void test5() throws JsonProcessingException {List<User> users = Arrays.asList(new User("a", "A", 1), new User("b", "B", 2));ObjectMapper mapper = new ObjectMapper();String jsonArray = mapper.writeValueAsString(users);System.out.println(jsonArray);// [{"username":"a","nickName":"A","userId":1},{"username":"b","nickName":"B","userId":2}]}

4.Map 转 JSON

@Testpublic void test6() throws JsonProcessingException {Map<String, Object> map = new HashMap<>();map.put("name", "admin");map.put("age", 25);ObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(map);System.out.println(json); // {"name":"admin","age":25}}

5.自定义日期格式

	@Testpublic void test7() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));User user = new User("admin", "若依", 1L);user.setCreateTime(new Date());String json = mapper.writeValueAsString(user);System.out.println(json);// {"username":"admin","createTime":"2025-05-13 15:00:00"}}

6.忽略空字段(NULL 或 EMPTY)

	@Testpublic void test8() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 字段User user = new User(null, "若依", null);String json = mapper.writeValueAsString(user);System.out.println(json); // {"nickName":"若依"}}

四、封装 Jackson 工具类(带注释)

下面是一个完整的 JsonUtils 工具类,用于统一 JSON 操作入口,便于后续维护和更换底层实现。

package com.wenge.business;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;import java.util.Collections;
import java.util.List;
import java.util.Map;/*** Jackson JSON 工具类*/
public class JsonUtils {private static final ObjectMapper mapper = new ObjectMapper();static {// 忽略未知字段,防止反序列化失败mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 忽略空对象不抛异常mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);// 支持 Java8 时间 API(LocalDate, LocalDateTime)mapper.registerModule(new JavaTimeModule());}/*** 对象转 JSON 字符串*/public static String toJson(Object obj) {try {return mapper.writeValueAsString(obj);} catch (JsonProcessingException e) {throw new RuntimeException("JSON serialize error", e);}}/*** JSON 字符串转 Java 对象*/public static <T> T fromJson(String json, Class<T> clazz) {try {return mapper.readValue(json, clazz);} catch (JsonProcessingException e) {throw new RuntimeException("JSON deserialize error", e);}}/*** JSON 字符串转复杂泛型对象(如 List<User>)*/public static <T> T fromJson(String json, TypeReference<T> typeReference) {try {return mapper.readValue(json, typeReference);} catch (JsonProcessingException e) {throw new RuntimeException("JSON deserialize error", e);}}/*** JSON 转 Map*/public static Map<String, Object> toMap(String json) {if (json == null || json.isEmpty()) {return Collections.emptyMap();}try {return mapper.readValue(json, new TypeReference<Map<String, Object>>() {});} catch (JsonProcessingException e) {throw new RuntimeException("JSON to Map error", e);}}/*** JSON 转 List*/public static <T> List<T> toList(String json, Class<T> elementType) {if (json == null || json.isEmpty()) {return Collections.emptyList();}try {return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, elementType));} catch (JsonProcessingException e) {throw new RuntimeException("JSON to List error", e);}}/*** 解析 JSON 字符串为 JsonNode*/public static JsonNode parseTree(String json) {try {return mapper.readTree(json);} catch (JsonProcessingException e) {throw new RuntimeException("JSON parse error", e);}}/*** 创建空的 ObjectNode*/public static ObjectNode createEmptyNode() {return mapper.createObjectNode();}/***解析 JSON 字符串为 ObjectNode**/public static ObjectNode parseObjectNode(String jsonStr, ObjectMapper mapper) throws Exception {JsonNode node = mapper.readTree(jsonStr);if (node.isObject()) {return (ObjectNode) node;} else {throw new IllegalArgumentException("JSON 字符串不是一个对象");}}}

五、现有 FastJSON 调用方式一键替换成 Jackson 的写法

如果你之前使用的是 FastJSON,可以参考以下对应表进行快速替换。

FastJSON 方法Jackson 替代方法示例
JSON.toJSONString(obj)JsonUtils.toJson(obj)JsonUtils.toJson(user)
JSON.parseObject(json, User.class)JsonUtils.fromJson(json, User.class)JsonUtils.fromJson(json, User.class)
JSON.parseObject(json, new TypeReference<List<User>>() {})JsonUtils.fromJson(json, new TypeReference<List<User>>() {})JsonUtils.fromJson(json, new TypeReference<List<User>>() {})
JSON.parseObject(json, Map.class)JsonUtils.toMap(json)JsonUtils.toMap(json)
JSON.parseArray(json, User.class)JsonUtils.toList(json, User.class)JsonUtils.toList(json, User.class)

六、替换步骤建议

  1. 创建 JsonUtils 工具类(见上文)

  2. 全局搜索替换关键字

    • JSON.toJSONString(JsonUtils.toJson(
    • JSON.parseObject(JsonUtils.fromJson(
    • new TypeReference<new TypeReference<
    • JSON.parseArray(JsonUtils.toList(
  3. 测试验证:对关键模块进行单元测试或接口测试,确保序列化/反序列化结果一致。

  4. 逐步上线:先灰度发布部分功能,确认无误后再全面切换。


七、补充建议

建议说明
✅ 统一 JSON 处理入口使用 JsonUtils 类统一调用,方便后期替换底层库
✅ 避免手动拼接 JSON易出错且难以维护,应始终使用序列化库生成 JSON
✅ 开启 Jackson 的严格模式防止非法字段、未知字段导致错误
✅ 使用泛型支持复杂结构TypeReference 支持嵌套结构、集合类型
✅ 日志中打印 JSON 时使用 pretty print方便调试,可使用 mapper.writerWithDefaultPrettyPrinter()

八、不同项目选择json库总结

场景推荐库
Spring Boot 项目✅ Jackson
微服务、分布式系统✅ Jackson
Android / Kotlin 项目✅ Moshi
简单工具类或小项目✅ Gson
已有项目迁出 FastJSON✅ fastjson2(过渡),尽快转 Jackson/Gson

相关文章:

  • Shell脚本实践(修改文件,修改配置文件,执行jar包)
  • 2025年中期大语言模型实力深度剖析
  • 如何使用远程桌面控制电脑
  • 【计算机视觉】OpenCV实战项目:基于OpenCV与face_recognition的实时人脸识别系统深度解析
  • 力扣hot100——347.前K个高频元素(cpp手撕堆)
  • 霍夫圆变换全面解析(OpenCV)
  • 在scala中使用sparkSQL连接MySQL并添加新数据
  • 需求跟踪矩阵准确性的5大策略
  • java使用 FreeMarker 模板生成包含图片的 `.doc` 文件
  • 《数据库原理》部分习题解析
  • MySQL——八、SQL优化
  • 精简大语言模型:用于定制语言模型的自适应知识蒸馏
  • 商业航天运动控制系统中的高可靠性芯片解决方案:挑战、策略与应用研究
  • 每周靶点分享:Nectin-4、CDH6及文献分享
  • Deno、Bun、Node.js 性能对比与选型指南
  • Linux进程信号处理(26)
  • Axure高级交互设计:文本框循环赋值实现新增、修改和查看
  • Codis集群搭建和集成使用的详细步骤示例
  • Chrome浏览器离线版安装包下载
  • TensorFlow之微分求导
  • 马上评|让查重回归促进学术规范的本意
  • 国际能源署:全球电动汽车市场强劲增长,中国市场继续领跑
  • 山西临汾哪吒主题景区回应雕塑被指抄袭:造型由第三方公司设计
  • “一码难求”的Manus开放注册但价格不菲,智能体距离“实用”还有多远
  • 福建厦门市副市长、市公安局局长陈育煌出任吉林省公安厅厅长
  • 教育部基础教育教指委:小学阶段禁止学生独自使用开放式内容生成功能