1. 概要

Javaで生のJSON値を操作する場合、それが有効かどうかを確認する必要がある場合があります。 これに役立つライブラリがいくつかあります: Gson JSON API 、およびJackson。 各ツールには、独自の利点と制限があります。

このチュートリアルでは、それぞれを使用してJSON String 検証を実装し、実際の例を使用してアプローチ間の主な違いを詳しく見ていきます。

2. JSONAPIによる検証

最も軽量でシンプルなライブラリはJSONAPIです。

String が有効なJSONであるかどうかを確認するための一般的なアプローチは、例外処理です。 その結果、 JSON解析を委任し、値が正しくない場合は特定のタイプのエラーを処理し、例外が発生しなかった場合は値が正しいと見なします

2.1. Mavenの依存関係

まず、jsonの依存関係をpom.xmlに含める必要があります。

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20211205</version>
</dependency>

2.2. JSONObjectによる検証

まず、 String がJSONであるかどうかを確認するために、 JSONObjectを作成しようとします。さらに、値が無効な場合は、JSONExceptionが発生します。

public boolean isValid(String json) {
    try {
        new JSONObject(json);
    } catch (JSONException e) {
        return false;
    }
    return true;
}

簡単な例で試してみましょう。

String json = "{\"email\": \"[email protected]\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));
String json = "Invalid_Json"; 
assertFalse(validator.isValid(json));

ただし、このアプローチの欠点は、  String はオブジェクトのみにすることができますが、JSONObjectを使用する配列にすることはできません。

たとえば、配列でどのように機能するかを見てみましょう。

String json = "[{\"email\": \"[email protected]\", \"name\": \"John\"}]";
assertFalse(validator.isValid(json));

2.3. JSONArrayによる検証

String がオブジェクトであるか配列であるかに関係なく検証するには、JSONObjectの作成が失敗した場合に条件を追加する必要があります。 同様に、JSONArrayはをスローしますJSONException文字列がJSON配列にも適合しない場合:

public boolean isValid(String json) {
    try {
        new JSONObject(json);
    } catch (JSONException e) {
        try {
            new JSONArray(json);
        } catch (JSONException ne) {
            return false;
        }
    }
    return true;
}

その結果、任意の値を検証できます。

String json = "[{\"email\": \"[email protected]\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));

3. ジャクソンによる検証

同様に、Jacksonライブラリは、Exception処理に基づいてJSONを検証する方法を提供します。 これは、多くの種類の解析戦略を備えた、より複雑なツールです。 ただし、使用する方がはるかに簡単です。

3.1. Mavenの依存関係

jackson-databindMaven依存関係を追加しましょう。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

3.2. ObjectMapperによる検証

readTree()メソッドを使用してJSON全体を読み取り、構文が正しくない場合はJacksonExceptionを取得します。

つまり、追加のチェックを提供する必要はありません。 オブジェクトと配列の両方で機能します。

ObjectMapper mapper = new ObjectMapper();

public boolean isValid(String json) {
    try {
        mapper.readTree(json);
    } catch (JacksonException e) {
        return false;
    }
    return true;
}

例を使ってこれをどのように使用できるか見てみましょう。

String json = "{\"email\": \"[email protected]\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));

String json = "[{\"email\": \"[email protected]\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));

String json = "Invalid_Json";
assertFalse(validator.isValid(json));

4. Gsonによる検証

Gsonは、同じアプローチを使用して生のJSON値を検証できるようにするもう1つの一般的なライブラリです。 これは、さまざまなタイプのJSON処理を使用したJavaオブジェクトマッピングに使用される複雑なツールです。

4.1. Mavenの依存関係

gsonMaven依存関係を追加しましょう。

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
</dependency>

4.2. 非厳密検証

Gsonは、指定されたJSONをJsonElementのツリーに読み込むためのJsonParserを提供します。 したがって、読み取り中にエラーが発生した場合にJsonSyntaxExceptionが発生することが保証されます。

したがって、 parse()メソッドを使用して、 String を計算し、JSON値の形式が正しくない場合にExceptionを処理できます。

public boolean isValid(String json) {
    try {
        JsonParser.parseString(json);
    } catch (JsonSyntaxException e) {
        return false;
    }
    return true;
}

主なケースをチェックするためにいくつかのテストを書いてみましょう:

String json = "{\"email\": \"[email protected]\", \"name\": \"John\"}";
assertTrue(validator.isValid(json));

String json = "[{\"email\": \"[email protected]\", \"name\": \"John\"}]";
assertTrue(validator.isValid(json));

このアプローチの主な違いは、Gsonのデフォルトの戦略では、JsonElementノードの一部として個別の文字列と数値が有効であると見なされることです。 つまり、単一の文字列または数値も有効であると見なされます。

たとえば、単一の文字列でどのように機能するかを見てみましょう。

String json = "Invalid_Json";
assertTrue(validator.isValid(json));

ただし、不正な形式などの値を考慮したい場合は、JsonParserに厳密な型ポリシーを適用する必要があります。

4.3. 厳密な検証

厳密な型ポリシーを実装するには、 TypeAdapter を作成し、JsonElementクラスを必須の型一致として定義します。 その結果、型がJSONオブジェクトまたは配列でない場合、 JsonParserJsonSyntaxExceptionをスローします。

fromJson()メソッドを呼び出して、特定のTypeAdapterを使用して生のJSONを読み取ることができます。

final TypeAdapter<JsonElement> strictAdapter = new Gson().getAdapter(JsonElement.class);

public boolean isValid(String json) {
    try {
        strictAdapter.fromJson(json);
    } catch (JsonSyntaxException | IOException e) {
        return false;
    }
    return true;
}

最後に、JSONが有効かどうかを確認できます。

String json = "Invalid_Json";
assertFalse(validator.isValid(json));

5. 結論

この記事では、Stringが有効なJSONであるかどうかを確認するさまざまな方法を見てきました。

それぞれのアプローチには、利点と制限があります。 JSON APIは単純なオブジェクト検証に使用できますが、Gsonは、JSONオブジェクトの一部として生の値の検証にさらに拡張できます。 ただし、ジャクソンの方が使いやすいです。 したがって、より適切なものを使用する必要があります。

また、一部のライブラリがすでに使用されているかどうか、または残りの目標にも適用されているかどうかを確認する必要があります。

いつものように、例のソースコードはGitHubから入手できます。