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。
相关推荐
dear_bi_MyOnly3 分钟前
【SpringBoot配置文件】
java·spring boot·后端·学习·spring·java-ee·学习方法
做个文艺程序员21 分钟前
Linux第22篇:用Docker容器化你的Java SaaS应用:一次构建,随处运行
java·docker·容器
冰暮流星32 分钟前
javascript之String方法介绍
开发语言·javascript·ecmascript
nianniannnn1 小时前
Qt QMessageBox知识点
开发语言·数据库·qt
故乡de云1 小时前
AWS 添加付款方式失败排查清单:卡片、银行风控与账号状态逐项定位
开发语言·php
其美杰布-富贵-李1 小时前
Spring Boot 依赖注入说明文档
java·spring boot·python
J_yyy1 小时前
【Qt核心组件类框架】
开发语言·qt
tachibana21 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
our_times2 小时前
2026年Java开发者破局指南:Spring AI 2.0 与 Agent 开发实战
java·人工智能·spring
运维行者_2 小时前
如何查看每个IP的带宽使用情况?NetFlow 技术实战指南
开发语言·网络·分布式·后端·架构·带宽