1概要

この記事では、JerseyやJacksonのようなサードパーティの依存関係を使用せずに、コアJava EEのみを使用してJSONを処理する方法を説明します。

使用するほとんどすべてのものはhttps://docs.oracle.com/javaee/7/api/javax/json/package-summary.html[javax.json]パッケージによって提供されます。


2 JSONへのオブジェクトの書き込み

String


JavaオブジェクトをJSONの

String

に変換するのはとても簡単です。単純な

Person

クラスがあるとしましょう。

public class Person {
    private String firstName;
    private String lastName;
    private Date birthdate;

   //getters and setters
}

そのクラスのインスタンスをJSONの

String

に変換するには、まず

httpsのインスタンスを作成する必要があります。

add()__メソッドを使用した/値ペア

JsonObjectBuilder objectBuilder = Json.createObjectBuilder()
  .add("firstName", person.getFirstName())
  .add("lastName", person.getLastName())
  .add("birthdate", new SimpleDateFormat("DD/MM/YYYY")
  .format(person.getBirthdate()));


add()

メソッドには、オーバーロードされたバージョンがいくつかあります。 2番目のパラメータとして、ほとんどのプリミティブ型(およびボックスオブジェクト)を受け取ることができます。

プロパティの設定が完了したら、オブジェクトを

String

に書き込むだけです。

JsonObject jsonObject = objectBuilder.build();

String jsonString;
try(Writer writer = new StringWriter()) {
    Json.createWriter(writer).write(jsonObject);
    jsonString = writer.toString();
}

以上です!生成された

String

は次のようになります。

{"firstName":"Michael","lastName":"Scott","birthdate":"06/15/1978"}


2.1.

JsonArrayBuilder

を使って配列を構築する

ここで、例をもう少し複雑にするために、

Person

クラスが、Eメールアドレスのリストを含む

emails

という新しいプロパティを追加するように変更されたとします。

public class Person {
    private String firstName;
    private String lastName;
    private Date birthdate;
    private List<String> emails;

   //getters and setters

}

そのリストのすべての値を

JsonObjectBuilder

に追加するには、


JsonArrayBuilder


のヘルプが必要です。

JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();

for(String email : person.getEmails()) {
    arrayBuilder.add(email);
}

objectBuilder.add("emails", arrayBuilder);


JsonArrayBuilder

オブジェクトを2番目のパラメーターとして使用する、

add()

メソッドのさらに別のオーバーロードバージョンを使用していることに注意してください。

それでは、2つの電子メールアドレスを持つ

Person

オブジェクトの生成されたStringを見てみましょう。

{"firstName":"Michael","lastName":"Scott","birthdate":"06/15/1978",
 "emails":["[email protected]","[email protected]"]}


2.2.

PRETTY

PRINTING__

を使用した出力のフォーマット

そのため、Javaオブジェクトを有効なJSON

String

に正常に変換しました。それでは、次のセクションに進む前に、出力をより「JSON風」で読みやすくするための簡単なフォーマットを追加しましょう。

前の例では、http://docs.oracle.com/javaee/7/api/javax/json/Json.html#createWriter-java.io.Writer-[

Json

.

createWriter()を使用して

JsonWriter

を作成しました静的メソッド。生成された

String

をより細かく制御するために、Java 7の


JsonWriterFactory

​​__を使用してライターを作成します。特定の設定

Map<String, Boolean> config = new HashMap<>();

config.put(JsonGenerator.PRETTY__PRINTING, true);

JsonWriterFactory writerFactory = Json.createWriterFactory(config);

String jsonString;

try(Writer writer = new StringWriter()) {
    writerFactory.createWriter(writer).write(jsonObject);
    jsonString = writer.toString();
}

コードは少し冗長に見えるかもしれませんが、実際にはあまり効果がありません。

まず、構成マップをそのコンストラクターに渡して

JsonWriterFactory

のインスタンスを作成します。マップには、PRETTY

PRINTINGプロパティをtrueに設定するエントリが1つだけ含まれています。次に、

Json.createWriter()__を使用する代わりに、そのファクトリインスタンスを使用してライターを作成します。

新しい出力には、JSON

String

を特徴付ける特有の改行と表が含まれます。

{
    "firstName":"Michael",
    "lastName":"Scott",
    "birthdate":"06/15/1978",
    "emails":[        "[email protected]",
        "[email protected]"
   ]}


3

String


からJava

Object

を構築する

逆の操作をしましょう:JSONの

String

をJavaのオブジェクトに変換しましょう。

変換プロセスの主要部分は、

JsonObject

を中心に展開されます。このクラスのインスタンスを作成するには、静的メソッド


Json.createReader()を使用します。


の後に


readObject()


:

JsonReader reader = Json.createReader(new StringReader(jsonString));

JsonObject jsonObject = reader.readObject();


createReader()

メソッドは

InputStream

をパラメータとして取ります。この例では、JSONが

String

オブジェクトに含まれているので

StringReaderを使用していますが、たとえば


FileInputStream

__。


JsonObject

のインスタンスが手元にあれば、

getString()

メソッドを使用してプロパティを読み取り、取得した値を

Person

クラスの新しく作成したインスタンスに割り当てることができます。

Person person = new Person();

person.setFirstName(jsonObject.getString("firstName"));
person.setLastName(jsonObject.getString("lastName"));
person.setBirthdate(dateFormat.parse(jsonObject.getString("birthdate")));


3.1.

JsonArray

を使用して

List

値を取得する


JsonObject

からリストの値を抽出するには、

JsonArray

という特別なクラスを使用する必要があります。

JsonArray emailsJson = jsonObject.getJsonArray("emails");

List<String> emails = new ArrayList<>();

for (JsonString j : emailsJson.getValuesAs(JsonString.class)) {
    emails.add(j.getString());
}

person.setEmails(emails);

それでおしまい! Jsonの

String

から

Person

の完全なインスタンスを作成しました。


4値の問い合わせ

それでは、JSONの

String

内にある非常に特定のデータに興味があるとしましょう。

以下のJSONがペットショップのクライアントを表しているとします。何らかの理由で、ペットリストから3番目のペットの名前を取得する必要があるとしましょう。

{
    "ownerName": "Robert",
    "pets":[{
        "name": "Kitty",
        "type": "cat"
    }, {
        "name": "Rex",
        "type": "dog"
    }, {
        "name": "Jake",
        "type": "dog"
    }]}

単一の値を取得するためだけにテキスト全体をJavaオブジェクトに変換するのは、あまり効率的ではありません。それでは、全体の変換試練を経ずにJSON

Strings

をクエリするためのいくつかの戦略をチェックしましょう。


4.1. オブジェクトモデルAPI

を使用したクエリ

JSON構造の既知の場所でプロパティの値を問い合わせるのは簡単です。前の例で使用したのと同じクラスである__JsonObjectのインスタンスを使用できます。

JsonReader reader = Json.createReader(new StringReader(jsonString));

JsonObject jsonObject = reader.readObject();

String searchResult = jsonObject
  .getJsonArray("pets")
  .getJsonObject(2)
  .getString("name");

ここでのキャッチは、正しいシーケンスの

get ** ()

メソッドを使用して

jsonObject

プロパティーをナビゲートすることです。

この例では、最初に

getJsonArray()



__を使用して「ペット」リストへの参照を取得します。これは3レコードのリストを返します。次に、

getJsonObject()

メソッドを使用します。これは、インデックスをパラメータとして受け取り、リストの3番目の項目を表す別の

JsonObject

を返します。最後に、探している文字列値を取得するために

getString()__を使用します。


4.2. ストリーミングAPIを使用したクエリ

JSON

String

に対して正確なクエリを実行するもう1つの方法は、ストリーミングAPIを使用することです。これには、


JsonParser


がメインとなっています。クラス。


JsonParser

は、JSへの非常に高速で読み取り専用の前方アクセスを提供しますが、オブジェクトモデルよりもやや複雑であるという欠点があります。

JsonParser jsonParser = Json.createParser(new StringReader(jsonString));

int count = 0;
String result = null;

while(jsonParser.hasNext()) {
    Event e = jsonParser.next();

    if (e == Event.KEY__NAME) {
        if(jsonParser.getString().equals("name")) {
            jsonParser.next();

            if(++count == 3) {
                result = jsonParser.getString();
                break;
            }
        }
    }
}

この例では、前の例と同じ結果が得られます。

pets

リストの3番目のペットの

name

を返します。



Json.createParser()


を使用して

JsonParser

を作成したら、次の手順を実行する必要があります。探している1つまたは複数のプロパティに到達するまで、JSONトークンをナビゲートするには、反復子(したがって

JsonParser

の「順方向アクセス」の性質)を使用します。

反復子を進むたびに、JSONデータの次のトークンに移動します。だから我々は現在のトークンが期待されるタイプを持っているかどうかチェックするように注意しなければならない。これは、

next()呼び出しによって返される


Event

__を確認することによって行われます。

トークンにはさまざまな種類があります。この例では、


http://docs.oracle.com/javaee/7/api/javax/json/stream/JsonParser.Event.html#KEY


NAME

型に興味があります。プロパティ(例:「ownerName」、「pets」、「name」、「type」)。 3回目に「name」の値を持つ

KEY

NAME

トークンを処理すると、次のトークンにはリストの3番目のペットの名前を表す文字列値が含まれることがわかります。

これは、Object Model APIを使用するよりも確実に困難です。特により複雑なJSON構造の場合は特にそうです。どちらを選択するかは、いつものように、あなたが対処する特定のシナリオに依存します。


5結論

Java EE JSON処理APIの基礎をいくつか簡単な例で説明しました。 JSON処理に関するその他の優れた点については、/jackson[一連のJackson記事]を参照してください。


GitHubレポジトリ

で、この記事で使用したクラスのソースコードと単体テストを確認してください。