杰瑞科技汇

Java JSON字符串转对象,怎么实现?

Java JSON 字符串转对象:从入门到精通,一篇搞定所有场景(附代码)

Meta 描述:

还在为 Java 中如何将 JSON 字符串转换成 Java 对象而烦恼?本文是全网最全面的Java JSON字符串转对象指南,涵盖 Jackson、Gson、Fastjson 三大主流库,从基础配置到高级用法,再到性能对比和避坑指南,手把手带你掌握,让你从此告别转换难题。

Java JSON字符串转对象,怎么实现?-图1
(图片来源网络,侵删)

引言:为什么 JSON 字符串转对象是 Java 开发者的必备技能?

在现代软件开发中,JSON(JavaScript Object Notation)已成为数据交换的事实标准,无论是 RESTful API 的响应、配置文件,还是消息队列中的数据,我们几乎无处不见它的身影,对于 Java 开发者而言,最常见的需求之一就是:如何将一个 JSON 格式的字符串,转换成一个我们熟悉的 Java 对象(POJO/Model)

这个过程,我们通常称之为“反序列化”(Deserialization),它的重要性不言而喻:

  • 提升效率:直接操作结构化的 Java 对象,远比手动解析字符串要方便、安全且高效。
  • 类型安全:编译器可以检查类型错误,避免在运行时才发现因数据类型不匹配导致的异常。
  • 代码可读性:将数据映射到业务模型对象,代码逻辑更清晰,更易于维护。

本文将作为你的终极指南,带你系统性地学习在 Java 中实现 JSON 字符串转对象的多种方法,并深入探讨其背后的原理和最佳实践。


第一部分:核心概念与准备工作

在开始编码之前,我们需要明确几个核心概念并准备好开发环境。

Java JSON字符串转对象,怎么实现?-图2
(图片来源网络,侵删)

什么是 JSON 字符串和 Java 对象?

  • JSON 字符串:一个符合 JSON 规范的文本字符串,{"name":"张三", "age":30, "isEmployee":true, "skills":["Java", "Python"]}
  • Java 对象:由我们自己定义的 Java 类(POJO - Plain Old Java Object)创建的实例,一个 User 类的实例。

我们的目标就是将前者“翻译”成后者。

主流 JSON 处理库对比

Java 生态中最流行的 JSON 库有三个,它们各有千秋:

库名 维护方 特点 适用场景
Jackson FasterXML 性能卓越、功能强大、社区活跃、Spring Boot 默认集成 首选推荐,几乎适用于所有场景,尤其是对性能有要求的 Web 应用。
Gson Google API 简洁、易于上手、对复杂泛型支持良好 Google 系项目,或偏爱简单 API 的开发者。
Fastjson 阿里巴巴 性能极高、API 丰富(支持 JSONPath 等) 国内互联网公司常用,但需注意历史版本的安全漏洞问题,建议使用最新版。

本文将以 Jackson 为主,Gson 为辅,进行详细讲解,因为它们是社区公认的最稳定、最可靠的选择。

项目环境准备

以 Maven 项目为例,你需要在 pom.xml 中添加相应依赖。

Java JSON字符串转对象,怎么实现?-图3
(图片来源网络,侵删)

Jackson 依赖:

<dependencies>
    <!-- Jackson Core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.15.2</version> <!-- 建议使用最新稳定版 -->
    </dependency>
    <!-- Jackson Databind (包含核心和注解功能) -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
</dependencies>

Gson 依赖:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version> <!-- 建议使用最新稳定版 -->
</dependency>

第二部分:Jackson 篇 - 业界标准的王者用法

Jackson 的核心 API 非常直观,主要依赖于 ObjectMapper 这个类。

基础转换:一对一映射

这是最简单也是最常见的情况,JSON 的键必须与 Java 对象的属性名完全匹配(或通过注解配置)。

步骤:

  1. 创建一个与 JSON 结构对应的 Java 类(POJO)。
  2. 创建 ObjectMapper 实例。
  3. 调用 objectMapper.readValue(jsonString, User.class) 方法。

代码示例:

a. 定义 Java 类

// User.java
public class User {
    private String name;
    private int age;
    private boolean isEmployee;
    // 必须提供无参构造函数,Jackson 在反序列化时会使用它
    public User() {
    }
    // Getters and Setters (非常重要!)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public boolean isEmployee() { return isEmployee; }
    public void setEmployee(boolean employee) { isEmployee = employee; }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", isEmployee=" + isEmployee +
                '}';
    }
}

b. 执行转换

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonMain {
    public static void main(String[] args) {
        String jsonString = "{\"name\":\"李四\", \"age\":28, \"isEmployee\":true}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 核心代码:将 JSON 字符串转为 User 对象
            User user = objectMapper.readValue(jsonString, User.class);
            // 验证结果
            System.out.println(user.getName()); // 输出: 李四
            System.out.println(user.getAge());  // 输出: 28
            System.out.println(user.isEmployee()); // 输出: true
            System.out.println(user); // 输出: User{name='李四', age=28, isEmployee=true}
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

进阶用法:处理复杂 JSON 结构

现实世界的 JSON 往往更复杂,比如嵌套对象、数组、集合等。

JSON 包含嵌套对象

JSON 字符串:

{
  "id": 101,
  "username": "admin",
  "profile": {
    "email": "admin@example.com",
    "signupDate": "2025-01-15"
  }
}

Java 类设计:

// Profile.java
public class Profile {
    private String email;
    private String signupDate;
    // Getters and Setters...
}
// UserWithProfile.java
public class UserWithProfile {
    private int id;
    private String username;
    private Profile profile; // 嵌套对象
    // Getters and Setters...
}

转换代码与基础版完全一致,Jackson 会自动处理嵌套关系。

JSON 包含数组或集合

JSON 字符串:

{
  "userId": 500,
  "username": "coder",
  "skills": ["Java", "Spring Boot", "MySQL"]
}

Java 类设计: 这里必须使用集合接口(如 List),而不是具体实现类(如 ArrayList)。

import java.util.List;
public class UserWithSkills {
    private int userId;
    private String username;
    private List<String> skills; // 使用 List 接口
    // Getters and Setters...
}

转换代码同样不变,Jackson 会自动将 JSON 数组转换为 ArrayList

Jackson 注解:让转换更灵活

当 JSON 键名与 Java 属性名不匹配,或者需要忽略某些字段时,Jackson 的注解就派上用场了。

注解 作用 示例
@JsonProperty 指定 JSON 属性名与 Java 属性名的映射 @JsonProperty("user_name") private String name;
@JsonIgnore 在序列化/反序列化时忽略该字段 @JsonIgnore private String password;
@JsonIgnoreProperties 类级别注解,忽略未知的属性 @JsonIgnoreProperties(ignoreUnknown = true)

示例:

@JsonIgnoreProperties(ignoreUnknown = true) // 忽略 JSON 中存在但类中没有的属性
public class AdvancedUser {
    @JsonProperty("user_id") // 将 JSON 的 "user_id" 映射到 "id" 属性
    private int id;
    @JsonIgnore // 忽略这个属性,不参与转换
    private String internalToken;
    // Getters and Setters...
}

第三部分:Gson 篇 - Google 的优雅方案

Gson 的 API 设计得非常“纯面向对象”,它的核心是 Gson 类。

基础转换

Gson 的用法与 Jackson 非常相似,同样需要 POJO 和 Getter/Setter 方法。

代码示例:

import com.google.gson.Gson;
public class GsonMain {
    public static void main(String[] args) {
        String jsonString = "{\"name\":\"王五\", \"age\":35, \"isEmployee\":false}";
        // 创建 Gson 实例
        Gson gson = new Gson();
        // 核心代码:将 JSON 字符串转为 User 对象
        User user = gson.fromJson(jsonString, User.class);
        // 验证结果
        System.out.println(user.getName()); // 输出: 王五
        System.out.println(user.getAge());  // 输出: 35
        System.out.println(user.isEmployee()); // 输出: false
    }
}

可以看到,Gson 的代码量更少,new Gson() 即可完成初始化,非常轻量。

Gson 的独特优势

Gson 在处理泛型和复杂类型时,API 显得更加优雅。

场景:反序列化为 List<User>

JSON 字符串 (数组形式):

[
  {"name":"赵六", "age":40},
  {"name":"钱七", "age":22}
]

使用 Jackson: 需要借助 TypeReference 来获取完整的泛型类型信息,否则会丢失类型。

ObjectMapper mapper = new ObjectMapper();
// 使用 TypeReference 来明确指定目标类型
List<User> userList = mapper.readValue(jsonStringString, new TypeReference<List<User>>() {});

使用 Gson: Gson 提供了 TypeToken 工具类,用法类似但感觉更符合 Java 生态。

import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
Gson gson = new Gson();
// 使用 TypeToken 来获取类型
Type userListType = new TypeToken<List<User>>() {}.getType();
List<User> userList = gson.fromJson(jsonString, userListType);

虽然看起来步骤相似,但 TypeToken 是 Gson 处理泛型的标准模式,社区认知度很高。


第四部分:性能对比与选型建议

特性 Jackson Gson Fastjson
性能 极快,数据流 API 性能最优 快,但通常略逊于 Jackson 极快,声称是最快的
功能 最全面,模块化设计,支持数据绑定、树模型、流 API 功能齐全,但模块化不如 Jackson 功能非常丰富,如 JSONPath 等
易用性 API 直观,学习曲线平缓 API 简洁,非常容易上手 API 丰富但有时略显复杂
生态/集成 Spring Boot 默认,生态最好 Google 官方,生态稳定 国内生态好,但历史有安全坑
泛型处理 TypeReference TypeToken 类似 Gson

选型建议:

  1. 无脑选 Jackson:如果你在开发一个新的 Spring Boot 项目,或者不确定用哪个,直接选择 Jackson,它性能好、功能强、社区支持最广,是业界最稳妥、最没有争议的选择。
  2. 选 Gson:如果你的项目是 Google 技术栈,或者你极度偏爱简洁的 API,并且不需要 Jackson 那些高级特性,Gson 是一个非常好的备选。
  3. 谨慎选 Fastjson:如果你的团队有使用 Fastjson 的丰富经验,并且对性能有极致要求,可以使用,但务必使用最新版本,并密切关注其安全公告,对于新项目,不推荐作为首选。

第五部分:常见问题与避坑指南

  1. UnrecognizedPropertyException

    • 问题:JSON 中有属性,但在 Java 类中找不到对应的字段。
    • 解决:在类上添加 @JsonIgnoreProperties(ignoreUnknown = true) 注解(Jackson/Gson 均有类似机制)或在配置中开启忽略未知属性。
  2. InvalidDefinitionException (no Creators, like default constructor, exist)

    • 问题:Java 类没有提供无参构造函数,这是 Jackson 反序列化时的硬性要求。
    • 解决:确保你的 POJO 类有一个 public 的无参构造函数。
  3. JsonMappingException (cannot deserialize from Object value)

    • 问题:数据类型不匹配,JSON 中期望一个字符串,但 Java 字段是 int 类型。
    • 解决:检查 JSON 数据和 Java 类的字段类型是否一致,可以使用 @JsonFormat 等注解进行格式转换。
  4. 循环引用

    • 问题:对象 A 中包含对象 B 的引用,而对象 B 又包含对象 A 的引用,序列化/反序列化时会栈溢出。
    • 解决:使用 @JsonIgnore 注解在其中一个引用上,或者使用 @JsonManagedReference@JsonBackReference(Jackson)来处理双向关系。

掌握 Java JSON 字符串转对象是每一位 Java 开发者的基本功,本文系统地介绍了业界最主流的 Jackson 和 Gson 库的使用方法,从简单的映射到复杂的嵌套和泛型处理,并提供了性能对比和实用的避坑指南。

核心要点回顾:

  • 首选 Jackson:凭借其强大的性能和 Spring 生态的加持,它是大多数场景下的最优解。
  • POJO 是基础:确保你的 Java 类有无参构造函数和标准的 Getter/Setter 方法。
  • 善用注解@JsonProperty@JsonIgnore 等注解是解决 JSON 与 Java 对象结构不匹配的利器。
  • 处理复杂类型:当面对 List 或泛型时,要使用 TypeReference (Jackson) 或 TypeToken (Gson) 来明确目标类型。

希望这篇详尽的指南能帮助你彻底攻克“Java JSON 字符串转对象”这一技术点,打开你的 IDE,动手实践一下吧!如果你有任何问题或想分享你的经验,欢迎在评论区留言讨论。

分享:
扫描分享到社交APP
上一篇
下一篇