Java常用的JSON

在 Java 中把对象转换为 JSON 对象(或 JSON 字符串),核心依赖 JSON 解析库,主流有 Jackson (Spring 内置)、FastJSON (阿里)、Gson(Google),以下是三种库的完整实现方案,包含核心 API、示例代码和避坑指南:

一、先明确:"JSON 对象" 的两种形态

  1. JSON 字符串 :最常用(如 {"name":"张三","age":20}),用于网络传输、存储;
  2. JSON 对象(树形结构) :如 Jackson 的 JsonNode、FastJSON 的 JSONObject,用于动态操作 JSON 节点(如新增 / 删除字段)。

二、方案 1:Jackson(Spring Boot 内置,推荐)

Spring Boot 项目默认集成 Jackson,无需额外引入核心依赖(非 Spring 项目需手动引入)。

1. 依赖引入(非 Spring 项目)
复制代码
<!-- Jackson 核心依赖 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>
<!-- 可选:支持 JDK8+ 时间类型(LocalDateTime) -->
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.15.2</version>
</dependency>
2. 核心用法
(1)对象转 JSON 字符串
复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;

// 测试实体类
class User {
    private String name;
    private Integer age;
    private Date createTime; // 时间字段
    // 必须有无参构造器(Jackson 反射实例化需要)
    public User() {}
    // getter/setter 必须有(Jackson 通过 getter 读取字段)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    public Date getCreateTime() { return createTime; }
    public void setCreateTime(Date createTime) { this.createTime = createTime; }
}

public class JacksonDemo {
    // 全局 ObjectMapper(线程安全,建议单例)
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        // 1. 构建对象
        User user = new User();
        user.setName("张三");
        user.setAge(20);
        user.setCreateTime(new Date());

        // 2. 对象转 JSON 字符串
        String jsonStr = objectMapper.writeValueAsString(user);
        System.out.println("JSON 字符串:" + jsonStr);
        // 输出示例:{"name":"张三","age":20,"createTime":1717238400000}
    }
}
(2)对象转 JSON 树形对象(JsonNode)

用于动态操作 JSON 节点(如修改字段、判断字段是否存在):

复制代码
public static void main(String[] args) throws Exception {
    User user = new User();
    user.setName("张三");
    user.setAge(20);

    // 1. 对象转 JsonNode(JSON 树形对象)
    com.fasterxml.jackson.databind.JsonNode jsonNode = objectMapper.valueToTree(user);

    // 2. 操作 JsonNode
    String name = jsonNode.get("name").asText(); // 获取字段值
    int age = jsonNode.get("age").asInt();       // 转换为int
    boolean hasCreateTime = jsonNode.has("createTime"); // 判断字段是否存在

    System.out.println("name:" + name + ",age:" + age + ",有createTime?" + hasCreateTime);
    // 输出:name:张三,age:20,有createTime?false
}
(3)自定义序列化规则(如日期格式)
复制代码
// 配置 ObjectMapper 自定义规则
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 日期格式
objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // 忽略空对象报错
objectMapper.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL); // 忽略null字段

// 转换后 JSON 示例:{"name":"张三","age":20,"createTime":"2025-06-01 10:00:00"}

三、方案 2:FastJSON(阿里,轻量高效)

FastJSON 是阿里开源的高性能 JSON 库,适合追求解析速度的场景。

1. 依赖引入
复制代码
<!-- FastJSON 2.x 版本(推荐,性能更优) -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.32</version>
</dependency>
<!-- 兼容 1.x 版本(如需) -->
<!--
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
-->
2. 核心用法
(1)对象转 JSON 字符串
复制代码
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import java.util.Date;

public class FastJsonDemo {
    public static void main(String[] args) {
        User user = new User();
        user.setName("李四");
        user.setAge(25);
        user.setCreateTime(new Date());

        // 1. 基础转换
        String jsonStr = JSON.toJSONString(user);
        System.out.println("基础JSON:" + jsonStr);

        // 2. 自定义规则(忽略null、格式化日期、美化输出)
        String jsonStrCustom = JSON.toJSONString(
            user,
            JSONWriter.Feature.WriteNulls, // 显示null字段(默认忽略)
            JSONWriter.Feature.PrettyFormat, // 美化输出(换行缩进)
            JSONWriter.Feature.WriteDateUseDateFormat // 日期格式化(默认yyyy-MM-dd HH:mm:ss)
        );
        System.out.println("自定义JSON:" + jsonStrCustom);
    }
}
(2)对象转 JSON 对象(JSONObject)
复制代码
public static void main(String[] args) {
    User user = new User();
    user.setName("李四");
    user.setAge(25);

    // 1. 对象转 JSONObject(FastJSON 树形对象)
    com.alibaba.fastjson2.JSONObject jsonObject = (com.alibaba.fastjson2.JSONObject) JSON.toJSON(user);

    // 2. 操作 JSONObject
    String name = jsonObject.getString("name");
    int age = jsonObject.getIntValue("age");
    jsonObject.put("gender", "男"); // 新增字段

    System.out.println("JSON对象:" + jsonObject);
    // 输出:{"age":25,"gender":"男","name":"李四"}
}

四、方案 3:Gson(Google,简洁易用)

Gson 是 Google 开源的 JSON 库,API 设计简洁,适合跨平台场景。

1. 依赖引入
复制代码
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>
2. 核心用法
(1)对象转 JSON 字符串
复制代码
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.Date;

public class GsonDemo {
    // 全局 Gson(线程安全)
    private static final Gson gson = new GsonBuilder()
            .setDateFormat("yyyy-MM-dd HH:mm:ss") // 日期格式
            .serializeNulls() // 显示null字段
            .setPrettyPrinting() // 美化输出
            .create();

    public static void main(String[] args) {
        User user = new User();
        user.setName("王五");
        user.setAge(30);
        user.setCreateTime(new Date());

        // 对象转 JSON 字符串
        String jsonStr = gson.toJson(user);
        System.out.println("Gson JSON:" + jsonStr);
    }
}
(2)对象转 JSON 树形对象(JsonObject)
复制代码
public static void main(String[] args) {
    User user = new User();
    user.setName("王五");
    user.setAge(30);

    // 1. 对象转 JsonElement(父类),强转为 JsonObject
    com.google.gson.JsonObject jsonObject = gson.toJsonTree(user).getAsJsonObject();

    // 2. 操作 JsonObject
    String name = jsonObject.get("name").getAsString();
    int age = jsonObject.get("age").getAsInt();
    jsonObject.addProperty("gender", "女"); // 新增字段

    System.out.println("Gson JSON对象:" + jsonObject);
    // 输出:{"name":"王五","age":30,"gender":"女"}
}

五、核心注意事项(避坑指南)

1. 基础要求(所有库通用)
  • 实体类必须有 无参构造器(Jackson/Gson 反射实例化需要,FastJSON 可兼容,但建议统一);
  • 字段必须有 getter 方法(序列化时读取字段值,FastJSON 可直接读字段,但 getter 更规范);
  • 避免循环引用(如 A 包含 B,B 包含 A),否则会报栈溢出错误:
    • Jackson:objectMapper.configure(SerializationFeature.FAIL_ON_CIRCULAR_REFERENCES, false)
    • FastJSON:JSON.toJSONString(user, SerializerFeature.DisableCircularReferenceDetect)
    • Gson:默认忽略循环引用(无需额外配置)。
2. 日期类型处理
  • 直接转换会得到时间戳(如 1717238400000),需手动配置日期格式(如 yyyy-MM-dd HH:mm:ss);
  • JDK8+ 时间类型(LocalDateTime/LocalDate):Jackson 需引入 jackson-datatype-jsr310,FastJSON/Gson 天然支持。
3. null 字段处理
  • Jackson:objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
  • FastJSON:默认忽略 null,需 JSONWriter.Feature.WriteNulls 显示;
  • Gson:默认忽略 null,需 GsonBuilder.serializeNulls() 显示。

六、库的选型建议

优点 缺点 适用场景
Jackson Spring 内置、稳定、功能全面 性能略低于 FastJSON Spring 项目、企业级开发
FastJSON 性能最高、轻量、API 简洁 早期版本有安全漏洞(需用 2.x) 高性能场景、阿里生态项目
Gson Google 维护、跨平台、易上手 性能一般 跨平台项目、小型应用

七、总结

  1. 快速转换为 JSON 字符串
    • Jackson:new ObjectMapper().writeValueAsString(obj)
    • FastJSON:JSON.toJSONString(obj)
    • Gson:new Gson().toJson(obj)
  2. 转换为 JSON 树形对象 (动态操作):
    • Jackson:objectMapper.valueToTree(obj)(JsonNode);
    • FastJSON:(JSONObject) JSON.toJSON(obj)
    • Gson:gson.toJsonTree(obj).getAsJsonObject()
  3. 核心原则:Spring 项目优先用 Jackson(无需额外依赖),追求性能用 FastJSON 2.x,简单场景用 Gson。
相关推荐
XWalnut几秒前
LeetCode刷题 day9
java·算法·leetcode
忧郁的Mr.Li2 分钟前
JAVA工具类---PDF电子签章工具类
java·pdf
aini_lovee4 分钟前
C# 快速搜索磁盘文件解决方案
开发语言·c#
小陈工4 分钟前
2026年4月8日技术资讯洞察:边缘AI推理框架竞争白热化,Python后端开发者的机遇与挑战
开发语言·数据库·人工智能·python·微服务·回归
零二年的冬9 分钟前
epoll详解
java·linux·开发语言·c++·链表
许杰小刀11 分钟前
MyBatis-Plus实战:Spring Boot数据库操作效率提升10倍
数据库·spring boot·mybatis
凭君语未可16 分钟前
Java 中的接口是什么
java·开发语言
XiYang-DING17 分钟前
【Java】二叉树
java·开发语言·数据结构
凌冰_27 分钟前
Servlet+Thymeleaf + Fetch 实现无刷新异步请求
java·servlet
下北沢美食家27 分钟前
JavaScript面试题2
开发语言·javascript·ecmascript