ジャクソンストリーミングAPI
1 。 概要
この記事では、JacksonStreamingAPIについて説明します。 読み取りと書き込みの両方をサポートし、それを使用することで、高性能で高速なJSONパーサーを作成できます。
反対に、使用するのは少し難しいです。JSONデータのすべての詳細をコードで明示的に処理する必要があります。
2. Mavenの依存関係
まず、jackson-coreにMaven依存関係を追加する必要があります。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.1</version>
</dependency>
3. JSONへの書き込み
JsonGenerator クラスを使用して、JSONコンテンツをOutputStreamに直接書き込むことができます。 まず、そのオブジェクトのインスタンスを作成する必要があります。
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 のインスタンスを使用して、特定のフィールドを OutputStream:に直接書き込むことができます。
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();
適切なJSONが作成されたかどうかを確認するために、JSONオブジェクトを含むStringオブジェクトを作成できます。
String json = new String(stream.toByteArray(), "UTF-8");
assertEquals(
json,
"{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}");
4. JSONの解析
JSON String を入力として取得し、そこから特定のフィールドを抽出する場合は、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<>();
入力JSONからparsedName、parsedAge、およびアドレスフィールドを取得します。 これを実現するには、低レベルの解析ロジックを処理し、それを自分で実装する必要があります。
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ドキュメントを解析するときに、特定の1つのフィールドだけに関心がある場合があります。
理想的には、このような状況では、ドキュメントの先頭のみを解析し、必要なフィールドが見つかったら、処理を中止できます。
入力JSONのageフィールドのみに関心があるとしましょう。 この場合、必要なフィールドが見つかったら解析を停止する解析ロジックを実装できます。
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("age".equals(fieldname)) {
jParser.nextToken();
parsedAge = jParser.getIntValue();
return;
}
}
jParser.close();
処理後、parsedAgeフィールドのみが次の値になります。
assertNull(parsedName);
assertEquals(parsedAge, (Integer) 25);
assertTrue(addresses.isEmpty());
そのおかげで、JSONドキュメントの解析は、ドキュメント全体を読み取る必要がなく、ドキュメントのごく一部を読み取る必要があるため、はるかに高速になります。
6. 結論
この簡単な記事では、JacksonからStreamProcessingAPIを活用する方法を見ていきます。
これらすべての例とコードスニペットの実装は、GitHubのにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。