核心概念:反序列化
将 JSON 字符串转换成 Java 对象的过程,在技术上称为 反序列化,这需要一个“映射”关系,即 JSON 中的键如何与 Java 对象中的属性(字段)对应起来。

使用 Jackson (最推荐)
Jackson 是目前 Java 生态中最流行、功能最强大的 JSON 处理库,Spring Framework 等许多主流框架都内置了它。
添加依赖
如果你使用 Maven,在 pom.xml 中添加依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 请使用最新版本 -->
</dependency>
如果你使用 Gradle,在 build.gradle 中添加:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2' // 请使用最新版本
创建 Java 类(POJO)
你需要一个与 JSON 结构对应的 Java 类,JSON 的键名需要与 Java 类的属性名一致(或者通过注解进行映射)。

示例 JSON:
{
"name": "张三",
"age": 30,
"isStudent": false,
"courses": [
"Java",
"Spring Boot"
],
"address": {
"city": "北京",
"street": "中关村大街1号"
}
}
对应的 Java 类:
User.java
import java.util.List;
import java.util.Map;
// 可以使用 @JsonIgnoreProperties(ignoreUnknown = true) 来忽略 JSON 中存在但 Java 类中没有的属性
// @JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String name;
private int age;
private boolean isStudent;
private List<String> courses;
private Address address; // 内部嵌套对象
// 必须提供一个无参构造函数,Jackson 在反序列化时会使用它
public User() {
}
// 建议提供 getter 和 setter 方法
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 isStudent() {
return isStudent;
}
public void setStudent(boolean student) {
isStudent = student;
}
public List<String> getCourses() {
return courses;
}
public void setCourses(List<String> courses) {
this.courses = courses;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
// 为了方便打印结果,重写 toString() 方法
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", isStudent=" + isStudent +
", courses=" + courses +
", address=" + address +
'}';
}
}
Address.java
public class Address {
private String city;
private String street;
public Address() {
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return "Address{" +
"city='" + city + '\'' +
", street='" + street + '\'' +
'}';
}
}
执行转换
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonJsonToJavaExample {
public static void main(String[] args) {
// 1. 创建 ObjectMapper 实例(它是线程安全的,可以全局共用一个)
ObjectMapper objectMapper = new ObjectMapper();
// 2. 定义 JSON 字符串
String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false,\"courses\":[\"Java\",\"Spring Boot\"],\"address\":{\"city\":\"北京\",\"street\":\"中关村大街1号\"}}";
try {
// 3. 调用 readValue 方法进行转换
// 第一个参数是 JSON 字符串
// 第二个参数是目标 Java 对象的 .class 文件
User user = objectMapper.readValue(jsonString, User.class);
// 4. 验证结果
System.out.println("转换成功!");
System.out.println(user);
System.out.println("用户姓名: " + user.getName());
System.out.println("用户所在城市: " + user.getAddress().getCity());
} catch (JsonProcessingException e) {
System.err.println("JSON 解析失败!");
e.printStackTrace();
}
}
}
输出:

转换成功!
User{name='张三', age=30, isStudent=false, courses=[Java, Spring Boot], address=Address{city='北京', street='中关村大街1号'}}
用户姓名: 张三
用户所在城市: 北京
使用 Gson
Google 的 Gson 是另一个非常流行的 JSON 库,使用起来同样非常简单。
添加依赖
Maven (pom.xml):
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version> <!-- 请使用最新版本 -->
</dependency>
Gradle (build.gradle):
implementation 'com.google.code.gson:gson:2.10.1' // 请使用最新版本
创建 Java 类
Java 类的创建与 Jackson 方式完全相同,这里不再重复,你需要 User.java 和 Address.java。
执行转换
import com.google.gson.Gson;
public class GsonJsonToJavaExample {
public static void main(String[] args) {
// 1. 创建 Gson 实例(它也是线程安全的,可以全局共用)
Gson gson = new Gson();
// 2. 定义 JSON 字符串
String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false,\"courses\":[\"Java\",\"Spring Boot\"],\"address\":{\"city\":\"北京\",\"street\":\"中关村大街1号\"}}";
try {
// 3. 调用 fromJson 方法进行转换
// 第一个参数是 JSON 字符串或 Reader
// 第二个参数是目标 Java 对象的 .class 文件
User user = gson.fromJson(jsonString, User.class);
// 4. 验证结果
System.out.println("转换成功!");
System.out.println(user);
System.out.println("用户姓名: " + user.getName());
System.out.println("用户所在城市: " + user.getAddress().getCity());
} catch (Exception e) {
System.err.println("JSON 解析失败!");
e.printStackTrace();
}
}
}
输出结果与 Jackson 示例完全相同。
高级用法与常见问题
JSON 键名与 Java 属性名不一致
当 JSON 中的键名(user_name)与 Java 类中的属性名(userName)不一致时,需要使用注解来建立映射关系。
示例 JSON:
{
"user_name": "李四",
"user_age": 25
}
Java 类 (使用 Jackson):
public class UserWithDifferentKey {
// @JsonProperty 注解用于将 JSON 中的 "user_name" 映射到 Java 属性 "userName"
@JsonProperty("user_name")
private String userName;
@JsonProperty("user_age")
private int userAge;
// ... getter, setter, toString ...
}
Java 类 (使用 Gson):
Gson 提供了类似的注解 @SerializedName。
import com.google.gson.annotations.SerializedName;
public class UserWithDifferentKey {
// @SerializedName 注解用于将 JSON 中的 "user_name" 映射到 Java 属性 "userName"
@SerializedName("user_name")
private String userName;
@SerializedName("user_age")
private int userAge;
// ... getter, setter, toString ...
}
处理 JSON 中的日期
JSON 本身没有标准的日期类型,通常用字符串表示,Jackson 和 Gson 都提供了强大的日期处理功能。
示例 JSON:
{
"name": "王五",
"birthDate": "1990-01-01"
}
Java 类 (使用 Jackson):
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class UserWithDate {
private String name;
// @JsonFormat 注解可以指定日期的格式
// pattern: 日期格式
// timezone: 时区
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date birthDate;
// ... getter, setter, toString ...
}
Java 类 (使用 Gson):
Gson 在创建 Gson 实例时可以配置日期格式。
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.Date;
// ...
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd") // 设置全局日期格式
.create();
将 JSON 转换为 Map 或 List
如果你不想创建对应的 Java 类,或者 JSON 结构非常动态,可以直接将其转换为 Map<String, Object> 或 List<Object>。
示例 (使用 Jackson):
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class JsonToMapExample {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"name\":\"赵六\",\"age\":40,\"city\":\"上海\"}";
// 使用 TypeReference 来明确指定泛型类型,这是关键!
Map<String, Object> dataMap = objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
System.out.println(dataMap);
System.out.println("姓名: " + dataMap.get("name"));
System.out.println("年龄: " + dataMap.get("age")); // 值是 Integer 类型
}
}
总结与推荐
| 特性 | Jackson | Gson |
|---|---|---|
| 流行度 | 非常高,是事实上的标准,Spring 默认使用。 | 非常高,Google 出品,稳定可靠。 |
| 性能 | 通常被认为性能更优,功能更强大。 | 性能也很好,但在某些极端场景下略逊于 Jackson。 |
| API 设计 | 功能全面,但 API 相对复杂一些。 | API 设计非常简洁、直观,易于上手。 |
| 数据绑定 | 支持强大的数据绑定、流式 API、树模型等。 | 主要专注于数据绑定,API 简单。 |
| 集成 | 与 Spring 等框架无缝集成。 | 需要手动配置,但集成也很容易。 |
如何选择?
- 新项目,特别是基于 Spring 的项目:强烈推荐 Jackson,因为它已经是生态的一部分,无需额外引入,并且功能最全面。
- 独立的小项目或追求 API 简洁性:Gson 是一个绝佳的选择,它的 API 非常干净,学习成本低。
- 需要处理复杂 JSON 或追求极致性能:Jackson 更有优势。
对于绝大多数 Java 熟练掌握 Jackson 是非常有必要的。
