1. 前言
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。在 Java 开发中,JSON 处理是一项非常常见且重要的任务。本文将详细介绍 Java 中处理 JSON 的各种实用技巧,包括主流 JSON 框架的使用、性能优化以及最佳实践。
Java 中处理 JSON 的三种主流框架:Gson、Jackson 和 Fastjson。内容包括基础用法、高级特性(自定义序列化、注解控制)、性能优化技巧及最佳实践。重点讲解了对象与集合的序列化和反序列化、复杂嵌套结构解析、日期时间处理及安全配置建议。通过统一工具类封装和流式 API 使用,帮助开发者高效、安全地在 Java 项目中处理 JSON 数据。

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。在 Java 开发中,JSON 处理是一项非常常见且重要的任务。本文将详细介绍 Java 中处理 JSON 的各种实用技巧,包括主流 JSON 框架的使用、性能优化以及最佳实践。
本文将重点介绍 Gson、Jackson 和 Fastjson 这三个主流 Java JSON 处理库的使用技巧和性能优化方法。
Java 生态中有多个优秀的 JSON 处理框架,每个框架都有其特点和适用场景。
Gson 是 Google 开发的 Java 库,用于将 Java 对象转换为 JSON 表示,以及将 JSON 字符串转换回等效的 Java 对象。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
// 创建 Gson 实例
Gson gson = new Gson();
// Java 对象转 JSON 字符串
User user = new User("张三", 25);
String json = gson.toJson(user);
System.out.println(json); // {"name":"张三","age":25}
// JSON 字符串转 Java 对象
String jsonString = "{\"name\":\"李四\",\"age\":30}";
User parsedUser = gson.fromJson(jsonString, User.class);
System.out.println(parsedUser.getName()); // 李四
// 序列化集合
List<User> userList = Arrays.asList(
new User("张三", 25),
new User("李四", 30)
);
String jsonList = gson.toJson(userList);
// 反序列化集合 - 方法 1:使用 TypeToken
Type userListType = new TypeToken<List<User>>(){}.getType();
List<User> parsedList = gson.fromJson(jsonList, userListType);
// 反序列化集合 - 方法 2:先转为数组再转集合
User[] userArray = gson.fromJson(jsonList, User[].class);
List<User> userList2 = Arrays.asList(userArray);
Gson gson = new GsonBuilder()
.setPrettyPrinting() // 格式化输出
.serializeNulls() // 序列化 null 值
.setDateFormat("yyyy-MM-dd HH:mm:ss") // 设置日期格式
.excludeFieldsWithoutExposeAnnotation() // 只序列化有@Expose 注解的字段
.registerTypeAdapter(Date.class, new DateSerializer()) // 注册自定义类型适配器
.disableHtmlEscaping() // 禁用 HTML 转义
.create();
// 自定义序列化器
public class UserSerializer implements JsonSerializer<User> {
@Override
public JsonElement serialize(User user, Type type, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("userName", user.getName()); // 字段名映射
jsonObject.addProperty("userAge", user.getAge());
return jsonObject;
}
}
// 自定义反序列化器
public class UserDeserializer implements JsonDeserializer<User> {
@Override
public User deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String name = jsonObject.get("userName").getAsString();
int age = jsonObject.get("userAge").getAsInt();
return new User(name, age);
}
}
// 注册使用
Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class, new UserSerializer())
.registerTypeAdapter(User.class, new UserDeserializer())
.create();
public class User {
@SerializedName("user_name") // 字段重命名
private String name;
@SerializedName(value = "user_age", alternate = {"age", "userAge"}) // 多字段名映射
private int age;
@Expose(serialize = true, deserialize = false) // 控制序列化和反序列化
private String password;
@Expose(serialize = false, deserialize = true)
private String email;
// getter 和 setter 方法...
}
// 注意:使用@Expose 需要配合 excludeFieldsWithoutExposeAnnotation()
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
// 使用 JsonElement 处理未知结构的 JSON
String complexJson = "{\"name\":\"张三\",\"address\":{\"city\":\"北京\",\"district\":\"朝阳区\"}}";
JsonElement jsonElement = JsonParser.parseString(complexJson);
JsonObject jsonObject = jsonElement.getAsJsonObject();
// 获取简单字段
String name = jsonObject.get("name").getAsString();
// 获取嵌套对象的字段
JsonObject addressObject = jsonObject.getAsJsonObject("address");
String city = addressObject.get("city").getAsString();
// 安全地获取可能不存在的字段
if (jsonObject.has("phone")) {
String phone = jsonObject.get("phone").getAsString();
}
**技巧:**Gson 2.8.6+版本中,JsonParser 的静态方法已被弃用,建议使用以下方式:
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(jsonString));
reader.setLenient(true);
JsonElement jsonElement = gson.fromJson(reader, JsonElement.class);
Jackson 是一个功能强大的 Java 库,用于处理 JSON 数据格式。它被广泛应用于 Spring 框架中,性能优异且功能丰富。
<!-- 核心依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
<!-- 可选:处理 XML -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.0</version>
</dependency>
// 创建 ObjectMapper 实例
ObjectMapper objectMapper = new ObjectMapper();
// Java 对象转 JSON 字符串
User user = new User("张三", 25);
String json = objectMapper.writeValueAsString(user);
System.out.println(json); // {"name":"张三","age":25}
// JSON 字符串转 Java 对象
String jsonString = "{\"name\":\"李四\",\"age\":30}";
User parsedUser = objectMapper.readValue(jsonString, User.class);
System.out.println(parsedUser.getName()); // 李四
// 格式化输出 JSON
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
// 序列化集合
List<User> userList = Arrays.asList(
new User("张三", 25),
new User("李四", 30)
);
String jsonList = objectMapper.writeValueAsString(userList);
// 反序列化集合
List<User> parsedList = objectMapper.readValue(
jsonList,
new TypeReference<List<User>>() {}
);
// 反序列化为 Map
Map<String, Object> map = objectMapper.readValue(
jsonString,
new TypeReference<Map<String, Object>>() {}
);
ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) // 忽略未知属性
.configure(SerializationFeature.INDENT_OUTPUT, true) // 格式化输出
.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false) // 不序列化 null 值
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) // 日期不使用时间戳
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")) // 设置日期格式
.registerModule(new JavaTimeModule()); // 支持 Java 8 日期时间 API
// 自定义序列化器
public class UserSerializer extends JsonSerializer<User> {
@Override
public void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("userName", user.getName());
jsonGenerator.writeNumberField("userAge", user.getAge());
jsonGenerator.writeEndObject();
}
}
// 自定义反序列化器
public class UserDeserializer extends JsonDeserializer<User> {
@Override
public User deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String name = node.get("userName").asText();
int age = node.get("userAge").asInt();
return new User(name, age);
}
}
// 注册使用
SimpleModule module = new SimpleModule();
module.addSerializer(User.class, new UserSerializer());
module.addDeserializer(User.class, new UserDeserializer());
objectMapper.registerModule(module);
public class User {
@JsonProperty("user_name") // 字段重命名
private String name;
@JsonIgnore // 忽略此字段
private String password;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 日期格式化
private Date createTime;
@JsonInclude(JsonInclude.Include.NON_NULL) // 只序列化非 null 值
private String email;
@JsonInclude(JsonInclude.Include.NON_EMPTY) // 只序列化非空值
private List<String> hobbies;
// getter 和 setter 方法...
}
// 使用 JsonNode 处理未知结构的 JSON
String complexJson = "{\"name\":\"张三\",\"address\":{\"city\":\"北京\",\"district\":\"朝阳区\"}}";
JsonNode rootNode = objectMapper.readTree(complexJson);
// 获取字段
String name = rootNode.get("name").asText();
String city = rootNode.get("address").get("city").asText();
// 安全地获取可能不存在的字段
if (rootNode.has("phone")) {
String phone = rootNode.get("phone").asText();
}
// 遍历数组
JsonNode arrayNode = rootNode.get("contacts");
if (arrayNode != null && arrayNode.isArray()) {
for (JsonNode node : arrayNode) {
String contactName = node.get("name").asText();
}
}
// 创建树模型
ObjectMapper mapper = new ObjectMapper();
ObjectNode rootNode = mapper.createObjectNode();
rootNode.put("name", "张三");
rootNode.put("age", 25);
// 创建嵌套对象
ObjectNode addressNode = mapper.createObjectNode();
addressNode.put("city", "北京");
addressNode.put("district", "朝阳区");
rootNode.set("address", addressNode);
// 创建数组
ArrayNode hobbiesNode = mapper.createArrayNode();
hobbiesNode.add("读书");
hobbiesNode.add("游泳");
rootNode.set("hobbies", hobbiesNode);
// 转换为 JSON 字符串
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
Fastjson 是阿里巴巴开发的 JSON 库,以其极高的性能著称,API 简洁易用。
**安全提示:**Fastjson 历史上存在一些安全漏洞,使用时请确保更新到最新版本,并根据官方建议进行安全配置。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
// Java 对象转 JSON 字符串
User user = new User("张三", 25);
String json = JSON.toJSONString(user);
System.out.println(json); // {"age":25,"name":"张三"}
// JSON 字符串转 Java 对象
String jsonString = "{\"name\":\"李四\",\"age\":30}";
User parsedUser = JSON.parseObject(jsonString, User.class);
System.out.println(parsedUser.getName()); // 李四
// 格式化输出
String prettyJson = JSON.toJSONString(user, SerializerFeature.PrettyFormat);
// 序列化集合
List<User> userList = Arrays.asList(
new User("张三", 25),
new User("李四", 30)
);
String jsonList = JSON.toJSONString(userList);
// 反序列化集合
List<User> parsedList = JSON.parseArray(jsonList, User.class);
// 反序列化为 JSONObject
JSONObject jsonObject = JSON.parseObject(jsonString);
String name = jsonObject.getString("name");
int age = jsonObject.getInteger("age");
// 配置序列化特性
String json = JSON.toJSONString(user,
SerializerFeature.PrettyFormat, // 格式化输出
SerializerFeature.WriteNullStringAsEmpty, // null 字符串输出为""
SerializerFeature.WriteNullNumberAsZero, // null 数字输出为 0
SerializerFeature.WriteNullBooleanAsFalse, // null 布尔值输出为 false
SerializerFeature.WriteNullListAsEmpty, // null 列表输出为 []
SerializerFeature.DisableCircularReferenceDetect, // 禁用循环引用检测
SerializerFeature.WriteDateUseDateFormat, // 日期格式化
SerializerFeature.WriteMapNullValue // 输出 null 值
);
// 自定义序列化器
public class UserSerializer implements ObjectSerializer {
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
User user = (User) object;
SerializeWriter out = serializer.out;
out.write('{');
out.writeFieldName("userName");
serializer.write(user.getName());
out.write(',');
out.writeFieldName("userAge");
serializer.write(user.getAge());
out.write('}');
}
}
// 自定义反序列化器
public class UserDeserializer implements ObjectDeserializer {
@Override
public User deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
JSONObject jsonObject = parser.parseObject();
String name = jsonObject.getString("userName");
int age = jsonObject.getInteger("userAge");
return new User(name, age);
}
@Override
public int getFastMatchToken() {
return 0;
}
}
// 注册使用
ParserConfig.getGlobalInstance().putDeserializer(User.class, new UserDeserializer());
SerializeConfig.getGlobalInstance().put(User.class, new UserSerializer());
public class User {
@JSONField(name = "user_name") // 字段重命名
private String name;
@JSONField(serialize = false) // 不序列化此字段
private String password;
@JSONField(deserialize = false) // 不反序列化此字段
private String token;
@JSONField(format = "yyyy-MM-dd HH:mm:ss") // 日期格式化
private Date createTime;
@JSONField(ordinal = 1) // 字段序列化顺序
private String email;
// getter 和 setter 方法...
}
// 创建 JSONObject
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "张三");
jsonObject.put("age", 25);
// 创建嵌套 JSONObject
JSONObject addressObject = new JSONObject();
addressObject.put("city", "北京");
addressObject.put("district", "朝阳区");
jsonObject.put("address", addressObject);
// 创建 JSONArray
JSONArray hobbiesArray = new JSONArray();
hobbiesArray.add("读书");
hobbiesArray.add("游泳");
jsonObject.put("hobbies", hobbiesArray);
// 转换为 JSON 字符串
String json = jsonObject.toJSONString();
// 解析复杂 JSON
JSONObject parsedObject = JSON.parseObject(complexJson);
String city = parsedObject.getJSONObject("address").getString("city");
JSONArray contacts = parsedObject.getJSONArray("contacts");
for (int i = 0; i < contacts.size(); i++) {
String contactName = contacts.getJSONObject(i).getString("name");
}
// 禁用 AutoType,防止反序列化漏洞
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// 如果需要使用 AutoType,建议使用白名单机制
ParserConfig parserConfig = ParserConfig.getGlobalInstance();
parserConfig.addAccept("com.example.model."); // 只允许反序列化指定包下的类
// 或者使用安全的 JSONReader
JSONReader jsonReader = new JSONReader(new StringReader(jsonString));
jsonReader.config(Feature.SupportAutoType, false);
// 1. 重用 Gson 实例
public class GsonHolder {
private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
.create();
public static Gson getGson() {
return GSON;
}
}
// 2. 使用 TypeAdapter 进行高性能序列化/反序列化
TypeAdapter<User> userAdapter = GsonHolder.getGson().getAdapter(User.class);
// 序列化到流
userAdapter.write(new JsonWriter(new FileWriter("user.json")), user);
// 从流反序列化
User user = userAdapter.read(new JsonReader(new FileReader("user.json")));
// 3. 避免使用 toJsonTree 再 toJson,直接使用 toJson
String json = GsonHolder.getGson().toJson(user);
// 1. 重用 ObjectMapper 实例
public class ObjectMapperHolder {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
public static ObjectMapper getObjectMapper() {
return OBJECT_MAPPER;
}
}
// 2. 使用流式 API 处理大型 JSON
// 序列化大型对象到文件
ObjectMapperHolder.getObjectMapper().writeValue(new File("large.json"), largeObject);
// 反序列化大型 JSON
LargeObject largeObject = ObjectMapperHolder.getObjectMapper()
.readValue(new File("large.json"), LargeObject.class);
// 3. 使用 JsonNode 高效处理部分字段
JsonNode rootNode = ObjectMapperHolder.getObjectMapper().readTree(jsonString);
String neededField = rootNode.get("neededField").asText();
// 4. 使用 TypeFactory 预构建复杂类型
JavaType listType = ObjectMapperHolder.getObjectMapper().getTypeFactory()
.constructCollectionType(List.class, User.class);
// 1. 使用 TypeReference 提高泛型反序列化性能
List<User> userList = JSON.parseObject(jsonList, new TypeReference<List<User>>() {});
// 2. 使用 JSONB 格式(Fastjson 2.0+)
byte[] bytes = JSONB.toJSONBBytes(user);
User parsedUser = JSONB.parseObject(bytes, User.class);
// 3. 自定义序列化过滤器提高性能
PropertyFilter propertyFilter = new PropertyFilter() {
@Override
public boolean apply(Object object, String name, Object value) {
// 只序列化需要的字段
return !"password".equals(name);
}
};
String json = JSON.toJSONString(user, propertyFilter);
// 4. 使用 JSONReader 处理大型 JSON
JSONReader reader = new JSONReader(new StringReader(largeJson));
reader.startObject();
while (reader.hasNext()) {
String key = reader.readString();
if ("neededField".equals(key)) {
String value = reader.readString();
// 处理需要的字段
} else {
reader.skipValue();
}
}
reader.endObject();
**注意:**性能优化需要根据具体场景进行测试和验证,不同的框架在不同场景下可能有不同的表现。建议使用 JMH 等基准测试工具进行性能对比。
// 示例:创建统一的 JSON 工具类
public class JsonUtils {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 序列化方法
public static String toJson(Object obj) {
try {
return OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 序列化失败", e);
}
}
// 反序列化方法
public static <T> T fromJson(String json, Class<T> clazz) {
try {
return OBJECT_MAPPER.readValue(json, clazz);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 反序列化失败", e);
}
}
// 反序列化集合
public static <T> List<T> fromJsonList(String json, Class<T> clazz) {
try {
return OBJECT_MAPPER.readValue(
json,
OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz)
);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 列表反序列化失败", e);
}
}
}
// 优雅处理 JSON 解析异常
try {
User user = JsonUtils.fromJson(jsonString, User.class);
// 处理用户对象
} catch (RuntimeException e) {
// 记录详细错误信息
log.error("JSON 解析失败:{}", jsonString, e);
// 友好的错误响应
throw new BusinessException("数据格式错误,请检查输入");
}
// 验证 JSON 格式
try {
ObjectMapperHolder.getObjectMapper().readTree(jsonString); // JSON 格式有效
} catch (Exception e) {
// JSON 格式无效
throw new IllegalArgumentException("无效的 JSON 格式");
}
**安全提示:**处理外部 JSON 数据时,务必注意安全问题,特别是反序列化操作可能导致远程代码执行漏洞。
// Jackson 安全配置
ObjectMapper mapper = new ObjectMapper();
// 禁用外部实体,防止 XXE 攻击
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 限制反序列化的类
mapper.registerModule(new SimpleModule()
.addDeserializer(Object.class, new SafeObjectDeserializer()));
// Fastjson 安全配置
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// 使用白名单
ParserConfig.getGlobalInstance().addAccept("com.example.model.");
// Gson 安全配置
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new SafeTypeAdapterFactory())
.create();
// Jackson 日期时间处理
ObjectMapper mapper = new ObjectMapper();
// 配置日期格式
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 支持 Java 8 日期时间 API
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// Gson 日期时间处理
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer())
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeDeserializer())
.create();
// Fastjson 日期时间处理
String json = JSON.toJSONString(dateObject, SerializerFeature.WriteDateUseDateFormat);
// 自定义日期格式
JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
String formattedJson = JSON.toJSONString(dateObject, SerializerFeature.WriteDateUseDateFormat);
**问题:**JSON 中的字段名与 Java 类中的字段名不一致,导致反序列化失败。
解决方案:
**问题:**JSON 中包含 null 值,如何控制其序列化和反序列化行为。
解决方案:
**问题:**对象之间存在循环引用,导致序列化时出现 StackOverflowError。
解决方案:
**问题:**JSON 结构复杂,难以直接映射到 Java 类。
解决方案:
**问题:**处理大型 JSON 数据时性能不佳。
解决方案:
通过本文介绍的技巧和最佳实践,相信您能够在 Java 项目中更加高效、安全地处理 JSON 数据。选择合适的工具,遵循最佳实践,将使您的代码更加健壮和可维护。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online