JSON(JavaScript Object Notation)は、アプリケーションによって簡単に解析および生成できるキーと値のコレクションです。これはJavaScriptプログラミング言語標準ECMA-262のサブセットです。JSONの解析は、restful APIやデータシリアライゼーションが必要なアプリケーションなど、ほとんどのアプリケーションで必要です。
Javaエコシステムでは、JSONデータを処理するための2つの最も人気のあるライブラリはJacksonとGsonです。どちらも広く使用され、独自の利点を提供しています。この記事では、両方のライブラリの機能を異なるパラメータについて探るために、エッジケースの例を使用します。
JacksonとGsonの簡単な概要
Jackson
JacksonはFasterXMLによって開発され、Spring Bootなどのエンタープライズアプリケーションやフレームワークで使用されています。JSONデータの解析、シリアライゼーション、および逆シリアライゼーションを提供しています。以下の機能がこのライブラリを開発者の間で人気にしています:
- JacksonはSpring BootでのデフォルトのJSON処理ライブラリであり、ほとんどの場合において手動での構成が不要です。
- TypeReferenceやJavaTypeを使用して、JSONの逆シリアライゼーションをジェネリック型に容易に行うことができます。
- 異なるアノテーションが提供され、シリアライゼーションと逆シリアライゼーションの動作をカスタマイズすることができます。たとえば、
@JsonProperty(name)
は、受信キーと実際のJava POJOフィールドのマッピングをシームレスに行います。 - Jacksonライブラリは、双方向のデータバインディング(JSONからPOJOへ、およびその逆)やストリーミングAPI(APIがJSONをPOJOに読み込む)およびツリーモデルの解析(JSONオブジェクトのインメモリマップ)に幅広くかつ堅牢なサポートを提供します。
- Jacksonライブラリは、メモリオーバーヘッドを最小限に抑え、シリアル化/デシリアル化(JSONからPOJOへ、およびその逆)を最適化することで高いパフォーマンスを提供します。
- Jacksonは、XML、YAML処理、Kotlin、Scala固有の拡張機能などの追加モジュールをサポートしています。
-
@JsonTypeInfo
や@JsonSubTypes
などのアノテーションは多態型を処理します。 - これは、JSONデータの欠落または追加フィールドを処理するため、後方および前方互換性を持っています。
- Jacksonは、イミュータブルなオブジェクトやコンストラクタを持つクラスをサポートし、ビルダーパターンを使用するオブジェクトも含まれます。
-
ObjectMapper
クラスはスレッドセーフであり、したがってマルチスレッドアプリケーションで効率的に使用することができます。
Gson
Gson は Googleによって開発され、JSONをJavaオブジェクト(POJO)に変換するために設計されています。小規模なアプリケーションで迅速な実装が必要な場合に簡単で理想的に使用できます。このオープンソースライブラリは、以下の主な機能を提供しています:
- Gsonには最小限の外部依存関係しかないため、統合が容易です。
- ネストされたオブジェクトやリスト、マップ、カスタムクラスなどの複雑なデータ型をサポートしています。
- TypeTokenを使用して、
List<T>
、Map<K,V>
などのジェネリックコレクションにJSONを逆シリアル化できます。 - GsonライブラリのJsonSerializerとJsonDeserializerインターフェースを使用すると、カスタム実装が可能です。
- デフォルトではJSON出力にはnull値が含まれず、必要に応じてnull値を出力に含めることができます。
- アノテーション
@SerializedName
は、JSONキーを異なる名前を持つJavaフィールドにマッピングします。 - Gsonオブジェクトはスレッドセーフであり、したがってマルチスレッドアプリケーションで使用できます。
- GsonBuilderクラスは、フィールドに対してカスタム命名ポリシーを適用できます。たとえば、
FieldNamingPolicy.IDENTITY
はデフォルトのポリシーであり、フィールド名が変更されないことを意味します。
この比較で考慮される特殊なケース
Feature | Jackson | GSON |
---|---|---|
追加フィールド |
デフォルトでは無視され、設定可能です。 |
デフォルトでは無視されます。 |
null値 |
@JsonIncludeをサポートしています。 |
.serializeNulls()を必要とします。 |
循環参照 |
@JsonIdentityInfoを使用してサポートされています。 |
直接サポートされていません。 |
データ処理 |
モジュールと共にJava 8の日付APIをサポートしています。 |
カスタムタイプアダプタが必要です。 |
ポリモーフィズム |
@JsonTypeInfoで組み込みです。 |
カスタム逆シリアル化ロジックが必要です。 |
JacksonおよびGsonライブラリと比較するために考慮される入力JSONはGitHubにあります。
JSONのモデルクラス表現はGitHubにあります。
Jacksonの実装
上記のJSONは、以下のJacksonライブラリを使用してJavaオブジェクトに変換されます:
<!-- Jackson START-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.2</version>
</dependency>
<!-- Jackson END-->
Jacksonライブラリを使用したJSONパースmainクラス:
public class JacksonJsonMain {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
//Jackson Support for LocalDate using jackson-datatype-jsr310
mapper.registerModule(new JavaTimeModule());
//Configuration to ignore extra fields
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Deserialize the JSON
EmployeeModelData employeeModelData = mapper.readValue(json, EmployeeModelData.class);
Employee employee=employeeModelData.getEmployee();
// display Json fields
System.out.println("Jackson Library parsing output");
System.out.println("Employee Name: " + employee.getName());
System.out.println("Department Name: " + employee.getDepartment().getName());
System.out.println("Skills: " + employee.getSkills());
System.out.println("Team Members Count: " + employeeModelData.getTeamMembers().size());
}
}
上記クラスの出力は次のとおりです:
Gsonの実装
上記JSONをJavaオブジェクトに変換するために使用されるGsonの依存関係は以下の通りです:
<!--GSON START -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!--GSON END -->
GSONライブラリを使用したJSONパースmainクラス:
public class GsonJsonMain {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // Register LocalDate adapter
.serializeNulls() // Handle null values
.setPrettyPrinting() // Pretty print JSON
.create();
// Deserialize the JSON
EmployeeModelData data = gson.fromJson(json, EmployeeModelData.class);
// Print Employee information
System.out.println("GSON Library parsing output");
System.out.println("Employee Name: " + data.getEmployee().getName());
System.out.println("Department Name: " + data.getEmployee().getDepartment().getName());
System.out.println("Skills: " + data.getEmployee().getSkills());
System.out.println("Team Members Count: " + data.getTeamMembers().size());
}
}
上記mainクラスの出力は次のとおりです:
どちらを選ぶべきか?
Jacksonは高性能を提供するため、プロジェクトが複雑なデータ構造や大規模なデータセットを含む場合に使用する必要があります。一方、Gsonは小規模なデータセットやデータ構造が単純な場合に使用する必要があります。
結論
どちらのライブラリも、上記のデータセットを効果的に処理し、JAVAでJSONパースを行う際に優れています。上記の比較は、プロジェクトの要件に基づいて適切なライブラリを選択するのに役立ちます。
上記のコードスニペットは、GitHubリポジトリで入手できます。
JacksonとGsonの詳細な比較は、Baeldungで提供されています。Jacksonの公式ドキュメントには、Jacksonの機能や設定に関する詳細な情報が提供されています。同様に、Gsonの公式ドキュメントには、詳細な実装ガイドが提供されています。
Source:
https://dzone.com/articles/jackson-vs-gson-edge-cases-json-parsing-java