Java用のJsonpathライブラリ

Jsonpath はかなり基本的な技術ツールですが、私はこれまで主に PostgreSQL データベースで使用してきました。最近の仕事では、Java レベルでいくつかの複雑な Json 構造を扱う必要があるため、JsonPath ツール ライブラリhttps://github.com/json-path/JsonPathを見つけました。

Jsonpath の構文についてはここでは説明しません。さまざまな関連ドキュメントを参照してください。Jsonpath は比較的人気のない概念であるため、異なる Jsonpath インタプリタによって実装される関数には詳細にいくつかの違いがあることに注意してください。テストする必要があります。その使用を確認するため。

このライブラリは非常にユーザーフレンドリーで、さまざまな柔軟性と複雑さのインターフェイスを提供します。ただし、いくつかの詳細はまだ比較的薄いので、後で詳しく説明します。ここでは、ドキュメントで強調されているものについてはあまり詳しく説明せず、そもそも見つけるのが比較的難しいものを紹介します。

基本的な使い方

JSON テキストから指定されたパスの内容を抽出するだけの場合は、次のような例で十分です。

import com.jayway.jsonpath.JsonPath;
// ... 
List<String> authors = JsonPath.read(json, "$.store.book[*].author");

正規表現など、クエリ内の一部の位置にはスペースを含めることができないことに注意してください。これはドキュメントには記載されていませんでしたが、実際の測定では問題が発生します。幸いなことに、 \s を使用して正規表現でスペースを表すことができます。正規表現の内容の深さに応じて、対応するエスケープ文字を忘れずに完成させてください。つまり、実際には \\s と記述する必要があります。

JsonPath.read(json, "$..book[?(@.author =~ /^J\\.\\s.*?/i)]");
//  [{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]

詳細はList(Json配列に相当)、Map、Javaの基本型とテキストに相当する型を自動変換しますが、より複雑な型マッピングが必要な場合は以下の内容を参照してください。

プリコンパイルされたクエリ

繰り返し使用される Jsonpath クエリの場合は、それらを JsonPath にプリコンパイルできます。

JsonPath query =JsonPath.compile("$.data.items");
List<String> books = query.read(content);

プリコンパイルされたドキュメント

逆に、再利用されるドキュメントも前処理することができます。

 DocumentContext doc =JsonPath.parse(content);
 Integer size = doc.read("$.data.items.length()");

型マッピング

前述したように、JsonPath は基本的な型と構造を直接処理できますが、カスタム型はどうなるでしょうか? 実際には、JsonProvider と MapProvider を設定することで解決できます。このメカニズムはまだ非常に透明です。デフォルトでは、独自の JsonProvider と MapProvider を使用しますが、Jackson と Gson もサポートします。

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.TypeRef;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
// ...
Configuration jsonPathConfig =
                Configuration.builder()
                        .jsonProvider(newJacksonJsonProvider(config.objectMapper()))
                        .mappingProvider(newJacksonMappingProvider(config.objectMapper()))
                        .build();
finalTypeRef<List<ContentItem>> itemsRef =newTypeRef<List<ContentItem>>() {
    };
// ...
List<ContentItem> items =JsonPath
                            .using(jsonPathConfig)
                            .parse(content)
                            .read("$.data.items", itemsRef);

これは、私が仕事で使用するテスト コードの一部です。コンテンツの実際の内容や ContentItem の内部構造を気にする必要はありません。重要なのは、TypeRef を介してワイプ メソッドをバイパスし、特定のリスト要素を渡すことです。 JsonPath プログラムに入力します。ここでは Jackson を使用していますが、Gson ユーザーは対応する設定を変更できます。コード実装の観点から見ると、これらのプロバイダーは複雑ではなく、ユーザーが FastJson などのサポートされていない Json ライブラリに対応するプロバイダーを作成することは難しくありません。

注意すべき点が 2 つあります。1 つは、JsonProvider と MapProvider の両方を提供する必要があることです。そうでない場合は、引き続き組み込みの JsonSmartJsonProvider が呼び出されます。次に、複合型を構築するときにエラーを報告します。

jsonPathConfig =
                Configuration.builder()
                        .jsonProvider(newJacksonJsonProvider(config.objectMapper()))
                        //.mappingProvider(new JacksonMappingProvider(config.objectMapper()))
                        .build();
// ...
List<ContentItem> items =JsonPath
                            .using(jsonPathConfig)
                            .parse(content)
                            .read("$.data.items", itemsRef);
//java.lang.UnsupportedOperationException: Json-smart provider does not support TypeRef! Use a Jackson or Gson based provider

この例では、JacksonMappingProvider の構成に注釈を付けましたが、スローされた例外は JsonProvider の問題を示しています。ここでの情報は少し誤解を招きます。

ここでのもう 1 つの詳細は、JacksonMappingProvider を構築するときに独自の ObjectMapper を渡すことができることです。これにより、JsonPath と Jackson の処理動作を均一に設定できるようになります。

インストール

JsonPath のインストール、通常の Maven リポジトリについては特別なことは何もありません。

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.7.0</version>
</dependency>

おすすめ

転載: blog.csdn.net/ccat/article/details/129653838