1. 概述

本文将深入探讨 Jackson 的流式 API(Streaming API)。它同时支持 JSON 的读写操作,通过合理使用,我们可以构建出高性能、快速解析的 JSON 处理器。

⚠️ 但需要提醒的是,这个 API 的使用门槛较高——JSON 数据的每个细节都需要在代码中显式处理,对开发者的耐心是个考验。

2. Maven 依赖

首先添加核心依赖(注意版本号以实际为准):

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.1</version>
</dependency>

3. 生成 JSON 内容

通过 JsonGenerator 类可以直接向 OutputStream 写入 JSON 数据。先创建实例:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory
  .createGenerator(stream, JsonEncoding.UTF8);

假设要生成如下结构的 JSON:

{  
   "name":"Tom",
   "age":25,
   "address":[  
      "Poland",
      "5th avenue"
   ]
}

使用 JsonGenerator 逐字段写入:

jGenerator.writeStartObject();
jGenerator.writeStringField("name", "Tom");
jGenerator.writeNumberField("age", 25);
jGenerator.writeFieldName("address");
jGenerator.writeStartArray();
jGenerator.writeString("Poland");
jGenerator.writeString("5th avenue");
jGenerator.writeEndArray();
jGenerator.writeEndObject();
jGenerator.close();

验证生成结果:

String json = new String(stream.toByteArray(), "UTF-8");
assertEquals(
  json, 
  "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}");

4. 解析 JSON

当需要从 JSON 字符串中提取特定字段时,可以使用 JsonParser

String json
  = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}";
JsonFactory jfactory = new JsonFactory();
JsonParser jParser = jfactory.createParser(json);

String parsedName = null;
Integer parsedAge = null;
List<String> addresses = new LinkedList<>();

需要手动实现底层解析逻辑:

while (jParser.nextToken() != JsonToken.END_OBJECT) {
    String fieldname = jParser.getCurrentName();
    if ("name".equals(fieldname)) {
        jParser.nextToken();
        parsedName = jParser.getText();
    }

    if ("age".equals(fieldname)) {
        jParser.nextToken();
        parsedAge = jParser.getIntValue();
    }

    if ("address".equals(fieldname)) {
        jParser.nextToken();
        while (jParser.nextToken() != JsonToken.END_ARRAY) {
            addresses.add(jParser.getText());
        }
    }
}
jParser.close();

解析完成后验证数据:

assertEquals(parsedName, "Tom");
assertEquals(parsedAge, (Integer) 25);
assertEquals(addresses, Arrays.asList("Poland", "5th avenue"));

5. 提取部分 JSON 字段

✅ 实际开发中,我们常常只需要 JSON 中的某个特定字段。理想情况下,应该只解析文档开头部分,找到目标字段后立即终止处理——这能显著提升性能。

假设我们只关心 age 字段:

while (jParser.nextToken() != JsonToken.END_OBJECT) {
    String fieldname = jParser.getCurrentName();

    if ("age".equals(fieldname)) {
        jParser.nextToken();
        parsedAge = jParser.getIntValue();
        return; // 找到目标后直接返回
    }
}
jParser.close();

验证结果(其他字段应为空):

assertNull(parsedName);
assertEquals(parsedAge, (Integer) 25);
assertTrue(addresses.isEmpty());

这种"按需解析"的方式,在处理大 JSON 文件时优势明显——无需读取整个文档,性能提升立竿见影。

6. 总结

本文展示了 Jackson 流式 API 的核心用法:

  • ✅ 高性能 JSON 生成与解析
  • ⚠️ 需要手动处理底层细节
  • ✅ 支持按需解析,适合处理大文件

所有示例代码可在 GitHub 项目 中找到(Maven 项目,可直接导入运行)。


原始标题:Jackson Streaming API | Baeldung