paint-brush
Manifold が Java での JSON 解析に革命を起こす方法@shai.almog
893 測定値
893 測定値

Manifold が Java での JSON 解析に革命を起こす方法

Shai Almog8m2023/05/02
Read on Terminal Reader

長すぎる; 読むには

Java (およびその他の形式) での JSON の解析は、JavaScript と同じくらい簡単です。タイプ セーフと深い IDE 統合を維持しながら、さらに多くのことができます。
featured image - Manifold が Java での JSON 解析に革命を起こす方法
Shai Almog HackerNoon profile picture

Java 開発者は、JSON の解析が容易な JavaScript をうらやましく思ってきました。 Java はより堅牢ですが、より多くの作業とボイラープレート コードを必要とする傾向があります。 Manifold プロジェクトのおかげで、Java は、JSON ファイルの解析と処理において JavaScript を凌駕する可能性を秘めています。


Manifold は、Java の言語拡張機能の革新的なセットであり、JSON の処理方法を完全に変えます (その他にも…)。

マニホールド入門

このチュートリアルのコードは、私のGitHub ページにあります。マニホールドは比較的新しいものですが、すでにその機能は膨大です。プロジェクトの詳細については、彼らの Web サイトと Slack チャンネルをご覧ください。


まず、現在 JetBrains IDE でのみ利用可能な Manifold プラグインをインストールする必要があります。このプロジェクトは、最新の JDK 19 を含む Java の LTS リリースをサポートしています。


マーケットプレイスに移動して Manifold を検索することで、IntelliJ/IDEAs 設定 UI からプラグインをインストールできます。プラグインは、IDE が Maven/Gradle プラグインによって行われる作業と衝突しないようにします。

画像の説明

Manifold は複数の小さなプロジェクトで構成され、それぞれがカスタム言語拡張を提供します。今日は、そのような拡張機能の 1 つについて説明しますが、さらに詳しく調べる必要があります。

Maven プロジェクトのセットアップ

Manifold のデモを行うために、単純な Maven プロジェクトを使用します (これは Gradle でも動作します)。まず、現在の Manifold バージョンを Web サイトから貼り付け、必要な依存関係を追加する必要があります。 JSON の主な依存関係は、 manifold-json-rt依存関係です。


YAML、XML、および CSV のサポートのために、他の依存関係を追加できます。これをプロジェクトのpom.xmlファイルに追加する必要があります。


JSON のボイラープレート削減が Maven ビルド スクリプトの大量の構成から始まるという皮肉なことは承知しています。ただし、これは構成であり、「実際のコード」ではありません。ほとんどコピー&ペーストです。


このコードを削減したい場合、Gradle の同等のコードは比較すると簡潔であることに注意してください。


この行は、プロパティ セクションに入る必要があります。

 <manifold.version>2023.1.5</manifold.version>


使用する依存関係は次のとおりです。

 <dependencies>   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-json-rt</artifactId>       <version>${manifold.version}</version>   </dependency>


コンパイル プラグインは、Manifold をバイトコードに織り込み、シームレスにするボイラープレートです。これは、pom セットアップの最後の部分です。

 <build>   <plugins>       <plugin>           <groupId>org.apache.maven.plugins</groupId>           <artifactId>maven-compiler-plugin</artifactId>           <version>3.8.0</version>           <configuration>               <source>19</source>               <target>19</target>               <encoding>UTF-8</encoding>               <compilerArgs>                   <!-- Configure manifold plugin-->                   <arg>-Xplugin:Manifold</arg>               </compilerArgs>               <!-- Add the processor path for the plugin -->               <annotationProcessorPaths>                   <path>                       <groupId>systems.manifold</groupId>                       <artifactId>manifold-json</artifactId>                       <version>${manifold.version}</version>                   </path>               </annotationProcessorPaths>           </configuration>       </plugin>   </plugins> </build>

セットアップが完了したら、コードに飛び込みましょう。

Manifold を使用した JSON の解析

リソース階層の下のプロジェクト ディレクトリにサンプルの JSON ファイルを配置します。このファイルをsrc/main/resources/com/debugagent/json/Test.jsonの下に配置しました。

 { "firstName": "Shai", "surname": "Almog", "website": "https://debugagent.com/", "active": true, "details":[ {"key": "value"} ] }


メイン クラスで Maven プロジェクトを更新すると、新しい Test クラスが表示されます。このクラスは、JSON ファイルに基づいて Manifold によって動的に作成されます。 JSON を変更して Maven を更新すると、すべてがシームレスに更新されます。


Manifold はコード ジェネレーターではないことを理解することが重要です。先ほど書き込んだ JSON をバイトコードにコンパイルします。


Test クラスには、ビルダー メソッドを使用して JSON オブジェクトを構築できるタイプ セーフなビルダー API など、いくつかの組み込み機能が付属しています。 write()およびtoJson()メソッドを使用して、ネストされたオブジェクトを生成し、JSON を文字列に変換することもできます。


これは、次のように記述できることを意味します。

 Test test = Test.builder().withFirstName("Someone") .withSurname("Surname") .withActive(true) .withDetails(List.of( Test.details.detailsItem.builder(). withKey("Value 1").build() )) .build();


次の JSON が出力されます。

 {  "firstName": "Someone",  "surname": "Surname",  "active": true,  "details": [    {      "key": "Value 1"    }  ] }


同様に、次のようなコードを使用して JSON ファイルを読み取ることができます。

 Test readObject = Test.load().fromJson(""" { "firstName": "Someone", "surname": "Surname", "active": true, "details": [ { "key": "Value 1" } ] } """);


長い文字列を書き込むための Java 15 TextBlock構文の使用に注意してください。 load()メソッドは、JSON を読み取るためのさまざまな API を含むオブジェクトを返します。この場合、 Stringから読み取られますが、URL やファイルなどから読み取るための API があります。


Manifold は、CSV、XML、YAML などのさまざまな形式をサポートしているため、ボイラープレート コードを記述したり型の安全性を犠牲にしたりすることなく、これらの形式を生成および解析できます。そのサポートを追加するには、追加の依存関係を pom.xml ファイルに追加する必要があります。

   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-csv-rt</artifactId>       <version>${manifold.version}</version>   </dependency>   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-xml-rt</artifactId>       <version>${manifold.version}</version>   </dependency>   <dependency>       <groupId>systems.manifold</groupId>       <artifactId>manifold-yaml-rt</artifactId>       <version>${manifold.version}</version>   </dependency> </dependencies>


これらの追加の依存関係により、このコードは JSON ファイルと同じデータを出力します... test.write().toCsv()を使用すると、出力は次のようになります。

 "firstName","surname","active","details" "Someone","Surname","true","[manifold.json.rt.api.DataBindings@71070b9c]"


カンマ区切り値 (CSV) の出力には、階層情報が含まれていないことに注意してください。これは CSV 形式の制限であり、Manifold のせいではありません。


test.write().toXml()を使用すると、出力はなじみがあり、驚くほど簡潔になります。

 <root_object firstName="Someone" surname="Surname" active="true">  <details key="Value 1"/> </root_object>


test.write().toYaml()を使用すると、おなじみの出力が得られます。

 firstName: Someone surname: Surname active: true details: - key: Value 1

JSON スキーマの操作

Manifold は JSON スキーマともシームレスに連携するため、厳格なルールと制約を適用できます。これは、日付と列挙型を扱う場合に特に便利です。


Manifold は、スキーマに準拠したバイト コードをシームレスに作成/更新するため、複雑な JSON データの操作がはるかに簡単になります。


このスキーマは、 Manifold GitHub プロジェクトからコピーして貼り付けたものです。

 { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/schemas/User.json", "type": "object", "definitions": { "Gender": { "type": "string", "enum": ["male", "female"] } }, "properties": { "name": { "type": "string", "description": "User's full name.", "maxLength": 80 }, "email": { "description": "User's email.", "type": "string", "format": "email" }, "date_of_birth": { "type": "string", "description": "Date of uses birth in the one and only date standard: ISO 8601.", "format": "date" }, "gender": { "$ref" : "#/definitions/Gender" } }, "required": ["name", "email"] }


これは比較的単純なスキーマですが、ここでいくつかのことに注意を向けたいと思います。必要に応じて名前と電子メールを定義します。これが、Manifold でビルダーを使用してUserオブジェクトを作成しようとすると、 build()メソッドに両方のパラメーターが必要な理由です。

 User.builder("Name", "[email protected]")


それは始まりにすぎません... スキーマには日付が含まれています。日付は JSON では厄介な問題です。標準化は不十分で、問題がたくさんあります。スキーマには、事実上列挙型である性別フィールドも含まれています。


これはすべて、LocalDate などの一般的な Java クラスを使用してタイプ セーフなセマンティクスに変換されます。

 User u = User.builder("Name", "[email protected]")       .withDate_of_birth(LocalDate.of(1999, 10, 11))       .withGender(User.Gender.male)       .build();


静的インポートを使用するとさらに短くすることができますが、アイデアの要点は明らかです。 JSON は事実上 Java in Manfold にネイティブです。

氷山の一角

Manifold はパワフルでエキサイティングなプロジェクトです。 Java での JSON 解析に革命をもたらしますが、それはできることのほんの一部にすぎません!


この投稿では、その機能の表面をなぞっただけです。次の記事では、Manifold をさらに深く掘り下げ、いくつかの予想外の追加機能について説明します。


コメント セクションで、Manifold に関するご経験やご意見をお聞かせください。ご不明な点がございましたら、お気軽にお問い合わせください。