Jackson Streaming API
Javaエコシステムで数年の経験があり、その経験をコミュニティと共有することに興味がある場合(そしてもちろん、あなたの仕事に対して報酬を得ることに興味がある場合)、"Write for Us" pageを見てください。 乾杯。 オイゲン
1. Overview
この記事では、Jackson Streaming APIについて説明します。 読み取りと書き込みの両方をサポートし、それを使用することで、高性能で高速なJSONパーサーを作成できます。
一方、使用するのは少し難しいです。JSONデータのすべての詳細をコードで明示的に処理する必要があります。
2. メーベン依存
まず、Mavenの依存関係をjackson-coreに追加する必要があります。
com.fasterxml.jackson.core
jackson-core
2.9.4
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の解析
JSONStringを入力として取得し、そこから特定のフィールドを抽出する場合は、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 addresses = new LinkedList<>();
入力JSONからparsedName, parsedAge, and addressesフィールドを取得したいと思います。 これを実現するには、低レベルの解析ロジックを処理し、自分で実装する必要があります。
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からStream ProcessingAPIを活用する方法を見ていきます。
これらすべての例とコードスニペットの実装はover on GitHubにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。