核心概念
-
JSON (JavaScript Object Notation): 一种轻量级的数据交换格式,它有两种主要结构:
(图片来源网络,侵删)- 对象: 无序的键/值对集合,用花括号 表示。
{"name": "张三", "age": 30},这天然就对应 Java 中的Map<String, Object>。 - 数组: 有序的值列表,用方括号
[]表示。[1, "a", true]。
- 对象: 无序的键/值对集合,用花括号 表示。
-
Java
Map: 一个键值对集合,最常用的实现是HashMap,它的键是唯一的,通常使用String类型,值可以是任意 Java 对象,这天然就对应 JSON 的对象。
JSON 对象 和 Map<String, Object> 在结构上是等价的。
使用 Jackson (推荐)
Jackson 是目前 Java 生态中最流行、性能最好的 JSON 处理库,Spring Boot、Solr 等许多主流框架都内置或推荐使用它。
添加 Maven 依赖
在你的 pom.xml 文件中添加 Jackson 的依赖:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 使用最新稳定版本 -->
</dependency>
Map 转 JSON
使用 ObjectMapper 的 writeValueAsString() 方法。
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
public class MapToJsonExample {
public static void main(String[] args) {
// 1. 创建一个 Map
Map<String, Object> userMap = new HashMap<>();
userMap.put("name", "李四");
userMap.put("age", 25);
userMap.put("isStudent", false);
userMap.put("courses", new String[]{"数学", "英语"}); // 嵌套数组
// 2. 创建 ObjectMapper 实例
ObjectMapper objectMapper = new ObjectMapper();
try {
// 3. 将 Map 转换为 JSON 字符串
String jsonString = objectMapper.writeValueAsString(userMap);
// 4. 输出结果
System.out.println("Map -> JSON:");
System.out.println(jsonString);
// 输出: {"name":"李四","age":25,"isStudent":false,"courses":["数学","英语"]}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
JSON 转 Map
使用 ObjectMapper 的 readValue() 方法。
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) {
String jsonString = "{\"name\":\"王五\",\"age\":30,\"city\":\"北京\"}";
ObjectMapper objectMapper = new ObjectMapper();
try {
// 关键:使用 TypeReference 来明确指定目标类型是 Map
// 因为 JSON 没有类型信息,需要告诉 Jackson 你想把它解析成什么
Map<String, Object> dataMap = objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
// 输出结果
System.out.println("JSON -> Map:");
System.out.println("Map: " + dataMap);
System.out.println("Name: " + dataMap.get("name")); // 输出: 王五
System.out.println("Age: " + dataMap.get("age")); // 输出: 30 (Integer类型)
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意: 为什么需要 TypeReference?
readValue 方法的第二个参数需要一个 Class 或 Type 对象。Map.class 只能告诉 Jackson 你想要一个 Map,但无法指定它的泛型类型(Map<String, Object>)。TypeReference 可以完整地保留这个泛型信息,让 Jackson 正确地进行反序列化。
使用 Gson
Google 的 Gson 是另一个非常受欢迎的 JSON 库,使用起来也很简单。

添加 Maven 依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version> <!-- 使用最新稳定版本 -->
</dependency>
Map 转 JSON
import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;
public class MapToJsonWithGson {
public static void main(String[] args) {
// 1. 创建一个 Map
Map<String, Object> productMap = new HashMap<>();
productMap.put("id", 101L);
productMap.put("title", "智能手机");
productMap.put("price", 4999.99);
productMap.put("inStock", true);
// 2. 创建 Gson 实例
Gson gson = new Gson();
// 3. 将 Map 转换为 JSON 字符串
String jsonString = gson.toJson(productMap);
// 4. 输出结果
System.out.println("Map -> JSON (Gson):");
System.out.println(jsonString);
// 输出: {"id":101,"title":"智能手机","price":4999.99,"inStock":true}
}
}
JSON 转 Map
Gson 的处理方式比 Jackson 更直接一些。
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;
public class JsonToMapWithGson {
public static void main(String[] args) {
String jsonString = "{\"username\":\"admin\",\"role\":\"superuser\",\"permissions\":[\"read\", \"write\"]}";
Gson gson = new Gson();
// 关键:使用 TypeToken 来获取正确的 Map 类型
Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
try {
// 直接进行转换
Map<String, Object> dataMap = gson.fromJson(jsonString, mapType);
// 输出结果
System.out.println("JSON -> Map (Gson):");
System.out.println("Map: " + dataMap);
System.out.println("Username: " + dataMap.get("username")); // 输出: admin
System.out.println("Permissions: " + dataMap.get("permissions")); // 输出: [read, write] (List类型)
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意: 为什么需要 TypeToken?
和 Jackson 的 TypeReference 原理类似,Java 的类型擦除导致在运行时 Map.class 丢失了泛型信息。TypeToken 通过创建一个匿名子类的方式,在运行时捕获并保留了完整的泛型类型 Map<String, Object>。
总结与对比
| 特性 | Jackson | Gson |
|---|---|---|
| 性能 | 非常快,内存占用低,功能强大。 | 速度很快,但通常略逊于 Jackson。 |
| 易用性 | API 功能全面,但初学者可能需要适应 ObjectMapper 和 TypeReference。 |
API 设计简洁直观,非常容易上手。 |
| 生态 | 行业标准,Spring Framework 默认使用。 | Google 出品,在 Android 开发中非常流行。 |
| 灵活性 | 提供流式 API、树模型、数据绑定等多种处理方式。 | 主要专注于数据绑定,功能相对聚焦。 |
| 依赖 | jackson-databind |
gson |
如何选择?
- 新项目,特别是基于 Spring Boot 的项目:强烈推荐 Jackson,它是事实上的标准,与 Spring 生态无缝集成,性能最优。
- Android 项目:推荐 Gson,它是 Android 开发中事实上的标准库。
- 简单、轻量级的需求:Gson 的 API 可能更简单直接。
- 需要高级功能(如自定义序列化/反序列化、过滤、数据格式化):Jackson 提供了更强大和灵活的 API。
手动处理 (不推荐)
理论上,你可以用字符串拼接和解析的方式手动转换,但这非常繁琐、容易出错,且无法处理复杂的嵌套结构。
// 手动 Map -> JSON (非常不推荐)
Map<String, String> map = new HashMap<>();
map.put("key", "value");
String json = "{\"" + map.keySet().iterator().next() + "\":\"" + map.values().iterator().next() + "\"}";
// 手动 JSON -> Map (非常不推荐)
String jsonStr = "{\"city\":\"上海\"}";
String content = jsonStr.substring(1, jsonStr.length() - 1); // 去掉 {}
String[] parts = content.split(":");
String key = parts[0].substring(1, parts[0].length() - 1); // 去掉 ""
String value = parts[1].substring(1, parts[1].length() - 1); // 去掉 ""
Map<String, String> manualMap = new HashMap<>();
manualMap.put(key, value);
永远不要在生产环境中手动处理 JSON,使用成熟的库可以让你专注于业务逻辑,而不是繁琐的格式转换和错误处理。
