跳到主要内容
Java 处理 JSON 的实战技巧与性能优化 | 极客日志
Java java
Java 处理 JSON 的实战技巧与性能优化 Java JSON 处理涉及多个主流框架的选择与配置。Gson 适合轻量级场景,Jackson 在 Spring 生态中表现优异,Fastjson 性能强劲但需注意安全。分享各框架的基础用法、高级特性及性能优化方案,涵盖自定义序列化、注解控制、复杂结构处理及安全配置。通过统一工具类封装和流式 API 应用,可有效提升开发效率与系统稳定性。
黑客 发布于 2026/3/23 更新于 2026/4/25 2 浏览前言
JSON 作为轻量级的数据交换格式,在 Java 开发中无处不在。无论是接口交互还是配置文件,处理得当与否直接影响系统的稳定性和性能。市面上可用的库不少,但最主流的当属 Gson、Jackson 和 Fastjson。本文将结合实战经验,聊聊这三个框架的使用细节、坑点规避以及性能调优方案。
JSON 处理框架对比
不同框架各有侧重,选型时得看具体场景。下图展示了三个主流框架的核心特性对比:
Gson 实战技巧
Gson 是 Google 出品的老牌库,API 简洁,适合对依赖体积敏感的场景。
基础用法
初始化一个 Gson 实例是第一步,注意它是线程安全的,建议全局复用。
Gson gson = new Gson ();
User user = new User ("张三" , 25 );
String json = gson.toJson(user);
System.out.println(json);
String jsonString = "{\"name\":\"李四\",\"age\":30}" ;
User parsedUser = gson.fromJson(jsonString, User.class);
System.out.println(parsedUser.getName());
处理集合类型时,泛型反序列化是个常见痛点。直接传 List<User>.class 会丢失类型信息,推荐使用 TypeToken。
Type userListType = new TypeToken <List<User>>(){}.getType();
List<User> parsedList = gson.fromJson(jsonList, userListType);
User[] userArray = gson.fromJson(jsonList, User[].class);
List<User> userList2 = Arrays.asList(userArray);
高级配置 默认行为未必符合业务需求,通过 GsonBuilder 可以精细控制。
Gson gson = new GsonBuilder ()
.setPrettyPrinting()
.serializeNulls()
.setDateFormat("yyyy-MM-dd HH:mm:ss" )
.excludeFieldsWithoutExposeAnnotation()
.registerTypeAdapter(Date.class, new DateSerializer ())
.disableHtmlEscaping()
.create();
注意: Gson 2.8.6+ 版本中,JsonParser 的静态方法已被弃用,建议使用 JsonReader 方式解析,兼容性更好。
Gson gson = new Gson ();
JsonReader reader = new JsonReader (new StringReader (jsonString));
reader.setLenient(true );
JsonElement jsonElement = gson.fromJson(reader, JsonElement.class);
对于复杂嵌套结构或未知格式的 JSON,直接使用 JsonElement 操作比强转对象更灵活。
String complexJson = "{\"name\":\"张三\",\"address\":{\"city\":\"北京\",\"district\":\"朝阳区\"}}" ;
JsonElement jsonElement = JsonParser.parseString(complexJson);
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonObject addressObject = jsonObject.getAsJsonObject("address" );
String city = addressObject.get("city" ).getAsText();
if (jsonObject.has("phone" )) {
String phone = jsonObject.get("phone" ).getAsString();
}
Jackson 实战技巧 Jackson 是 Spring Boot 的默认 JSON 库,生态完善,性能强劲,企业级开发首选。
基础用法 核心类是 ObjectMapper,同样建议单例复用。
ObjectMapper objectMapper = new ObjectMapper ();
User user = new User ("张三" , 25 );
String json = objectMapper.writeValueAsString(user);
String jsonString = "{\"name\":\"李四\",\"age\":30}" ;
User parsedUser = objectMapper.readValue(jsonString, User.class);
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
处理泛型集合时,Jackson 提供了 TypeReference,写法比 Gson 的 TypeToken 更直观。
List<User> parsedList = objectMapper.readValue(
jsonList,
new TypeReference <List<User>>() {}
);
Map<String, Object> map = objectMapper.readValue(
jsonString,
new TypeReference <Map<String, Object>>() {}
);
高级配置 ObjectMapper 的配置项非常丰富,能应对各种边界情况。
ObjectMapper objectMapper = new ObjectMapper ()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false )
.configure(SerializationFeature.INDENT_OUTPUT, true )
.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false )
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false )
.setDateFormat(new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ))
.registerModule(new JavaTimeModule ());
如果需要对特定字段进行特殊处理,或者完全控制 JSON 生成过程,可以实现 JsonSerializer 和 JsonDeserializer。
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();
}
}
SimpleModule module = new SimpleModule ();
module .addSerializer(User.class, new UserSerializer ());
objectMapper.registerModule(module );
对于动态结构或需要遍历修改的 JSON,JsonNode 树模型非常有用。
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();
JsonNode arrayNode = rootNode.get("contacts" );
if (arrayNode != null && arrayNode.isArray()) {
for (JsonNode node : arrayNode) {
String contactName = node.get("name" ).asText();
}
}
Fastjson 实战技巧 Fastjson 以高性能著称,API 设计偏向便捷,但在安全性上需要格外小心。
基础用法 阿里巴巴出品,使用 JSON 工具类即可,无需额外实例化。
User user = new User ("张三" , 25 );
String json = JSON.toJSONString(user);
String jsonString = "{\"name\":\"李四\",\"age\":30}" ;
User parsedUser = JSON.parseObject(jsonString, User.class);
String prettyJson = JSON.toJSONString(user, SerializerFeature.PrettyFormat);
高级特性 Fastjson 提供了丰富的 SerializerFeature 来控制输出行为,比如空值处理、循环引用检测等。
String json = JSON.toJSONString(user,
SerializerFeature.PrettyFormat,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.DisableCircularReferenceDetect
);
安全提示: Fastjson 历史上存在过严重的安全漏洞(如反序列化漏洞)。生产环境务必升级到最新稳定版,并严格限制 AutoType 功能。
ParserConfig.getGlobalInstance().setAutoTypeSupport(false );
ParserConfig parserConfig = ParserConfig.getGlobalInstance();
parserConfig.addAccept("com.example.model." );
性能优化技巧 在实际项目中,JSON 处理往往是高频操作,优化得当能显著提升吞吐量。
通用原则
重用对象: Gson、ObjectMapper 都是线程安全的,千万不要每次请求都 new 一个新实例,这会造成巨大的 GC 压力。
避免不必要的转换: 尽量直接在流上操作,减少中间字符串的创建。
选择合适的解析模式: 只需要部分字段时,优先使用流式 API 而不是树模型。
各框架优化示例 Gson: 使用 TypeAdapter 可以进一步提升特定类型的序列化效率。
TypeAdapter<User> userAdapter = GsonHolder.getGson().getAdapter(User.class);
userAdapter.write(new JsonWriter (new FileWriter ("user.json" )), user);
Jackson: 处理大文件时,直接写入 File 对象比转成 String 内存占用更小。
ObjectMapperHolder.getObjectMapper().writeValue(new File ("large.json" ), largeObject);
LargeObject largeObject = ObjectMapperHolder.getObjectMapper()
.readValue(new File ("large.json" ), LargeObject.class);
Fastjson: 使用 JSONB 二进制格式可以大幅提升序列化速度,但兼容性稍差。
byte [] bytes = JSONB.toJSONBBytes(user);
User parsedUser = JSONB.parseObject(bytes, User.class);
最佳实践与总结
统一封装 不要到处调用框架 API,建议封装统一的工具类,方便后续切换实现或增加日志监控。
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);
}
}
}
错误处理 外部传入的 JSON 数据不可信,必须捕获异常并给出友好提示,避免将堆栈信息直接暴露给前端。
try {
User user = JsonUtils.fromJson(jsonString, User.class);
} catch (RuntimeException e) {
log.error("JSON 解析失败:{}" , jsonString, e);
throw new BusinessException ("数据格式错误,请检查输入" );
}
选型建议
Spring 项目: 无脑选 Jackson,集成度最高。
追求极致性能: 考虑 Fastjson,但务必做好安全加固。
轻量级/Android: Gson 依然是不错的选择。
最后提醒一点,无论选哪个库,都要保持版本更新,特别是涉及安全补丁的部分。对于复杂的 JSON 处理逻辑,提前进行 JMH 基准测试,确保不会成为系统瓶颈。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online