1. 概述
本文将介绍两种将 BufferedReader
转换为 JSONObject
的方法,适用于使用 org.json
库处理流式 JSON 数据的场景。
实际开发中,我们常从网络、文件或 API 响应中读取 JSON 数据,输入流通常封装为 BufferedReader
。如何高效、安全地将其转为 JSONObject
是个高频需求。下面两种方式,一个简洁,一个兼容性强,看你的 Java 环境和依赖版本怎么选。
2. 依赖配置
使用 org.json
库前,先在 pom.xml
中引入依赖:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
✅ 推荐使用较新版本(如 20240303
),支持直接从 Reader
构造 JSON,避免中间转换。
3. 使用 JSONTokener(推荐方式)
org.json
的新版本提供了一个非常实用的类:JSONTokener
,它的构造函数直接接受 Reader
类型参数,这意味着你可以把 BufferedReader
原样传进去,无需转成字符串。
✅ 这种方式内存友好、代码简洁,是当前最推荐的做法。
示例代码如下:
@Test
public void givenValidJson_whenUsingBufferedReader_thenJSONTokenerConverts() {
byte[] b = "{ \"name\" : \"John\", \"age\" : 18 }".getBytes(StandardCharsets.UTF_8);
InputStream is = new ByteArrayInputStream(b);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
JSONTokener tokener = new JSONTokener(bufferedReader);
JSONObject json = new JSONObject(tokener);
assertNotNull(json);
assertEquals("John", json.get("name"));
assertEquals(18, json.get("age"));
}
⚠️ 注意:JSONTokener
会消费流(即读取并关闭),确保流的生命周期可控,避免后续重复读取失败。
4. 先转换为 String(兼容旧版本)
如果你的项目还在用老版本的 org.json
(比如 < 2023 版本),不支持 JSONTokener(Reader)
,那就得先将 BufferedReader
读成字符串,再用字符串构造 JSONObject
。
虽然多了一步,但胜在兼容性好,属于“踩坑”后常见的 fallback 方案。
实现方式也很简单:
@Test
public void givenValidJson_whenUsingString_thenJSONObjectConverts()
throws IOException {
byte[] b = "{ \"name\" : \"John\", \"age\" : 18 }".getBytes(StandardCharsets.UTF_8);
InputStream is = new ByteArrayInputStream(b);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
JSONObject json = new JSONObject(sb.toString());
assertNotNull(json);
assertEquals("John", json.get("name"));
assertEquals(18, json.get("age"));
bufferedReader.close();
}
❌ 踩坑提醒:
- 多次
readLine()
拼接时,别忘了处理换行符。如果原始 JSON 被分行读取,直接拼接可能导致语法错误。建议使用sb.append(line).append("\n")
或统一去除换行。 - 大文件场景下,
StringBuilder
可能引发内存溢出,慎用。
5. 总结
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
✅ JSONTokener(bufferedReader) |
代码简洁、内存友好、无需中间字符串 | 需要较新版本 org.json |
推荐新项目使用 |
✅ 先转 String 再构造 |
兼容老版本库 | 内存占用高、有性能开销 | 老系统维护、无法升级依赖时 |
📌 结论:优先使用 JSONTokener
方式,简单粗暴又高效。只有在受限于旧版本时,才退而求其次转成字符串。
完整示例代码已托管至 GitHub: 👉 https://github.com/baeldung/tutorials/tree/master/core-java-modules/core-java-io-conversions-2