プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle WebLogic Server 12.1.3アプリケーションの開発
12c (12.1.3)
E57574-04
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

10 Java API for JSON Processing

WebLogic Server 12.1.3では、JSR-353リファレンス実装を含めることにより、Java API for JSON Processing 1.0 (JSR 353)の仕様をサポートし、これをWebLogic Serverインスタンスにデプロイされるアプリケーションで使用できるようにしています。

この章の内容は次のとおりです。

JSONの概念の詳細は、Java EE 7チュートリアル(http://docs.oracle.com/javaee/7/tutorial/jsonp.htm)の「JSON Processing」の章を参照してください。

JavaScript Object Notation (JSON)について

JSONは軽量なデータ交換形式で、インターネット経由で相互通信するアプリケーションのデータのシリアライズおよびデシリアライズ用の一般的な形式として、広く使用されています。このようなアプリケーションは、異なるプログラミング言語で作成され、まったく異なる環境で実行されることがよくあります。JSONはオープンな標準であり、読取りと書込みが簡単で、他の表現よりコンパクトなため、このような使用例に適しています。RESTful Webサービスでは通常、リクエストとレスポンス内のデータの形式としてJSONが広く利用されており、JSONには終了タグがないため、JSON表現は対応するXML表現よりも通常はコンパクトです。

Java API for JSON Processingは、JSONテキストの処理(解析、生成、変換、問合せ)に便利です。JSONデータの生成および解析用に、XMLドキュメントで使用されるものと同じような2つのプログラミング・モデルが用意されています。

  • オブジェクト・モデルでは、メモリー内のJSONデータを示すツリーが作成されます。このツリーは参照と分析が可能です。メモリー内で生成されたJSONデータは不変であり、変更できませんが、オブジェクト・モデルは非常に柔軟で、ツリーのすべてのコンテンツにアクセスする必要がある処理に使用できます。ただし、通常はストリーミング・モデルより低速で、より多くのメモリーが必要です。このオブジェクト・モデルでは、ツリー全体を瞬時に参照して、JSON出力が生成されます。

    オブジェクト・モデルの使用方法の詳細は、「オブジェクト・モデルAPI」を参照してください。

  • ストリーミング・モデルでは、JSONデータの要素を一度に1つずつ読み取るイベント・ベースのパーサーを使用します。パーサーによってイベントが生成され、オブジェクトや配列の開始または終了時、キーや値の検出時には処理が停止されます。各要素はアプリケーション・コードごとに処理または破棄することができ、パーサーは次のイベントに進みます。このアプローチは、要素の処理に残りのデータからの情報が不要なローカル処理に適しています。ストリーミング・モデルでは、一度に1つの要素を使う関数コールにより、所定のストリームにJSON出力が生成されます。

    ストリーミング・モデルの使用方法の詳細は、「ストリーミングAPI」を参照してください。

オブジェクト・モデルAPI

オブジェクト・モデルAPIは、JSONオブジェクトおよび配列構造の不変のオブジェクト・モデルを提供する高レベルなAPIです。これらのJSON構造は、JavaのJsonObject型およびJsonArray型を使用するオブジェクト・モデルとして表現されます。インタフェースjavax.json.JsonObjectにはマップ・ビューがあり、ゼロ(0)個以上の名前/値ペアの、順不同のコレクションにモデルからアクセスできます。同様に、javax.json.JsonArrayインタフェースにはリスト・ビューがあり、ゼロ(0)個以上の連続した値にモデルからアクセスできます。

オブジェクト・モデルAPIでは、ビルダー・パターンを使用してこれらのオブジェクト・モデルを作成します。javax.json.JsonObjectBuilderおよびjavax.json.JsonArrayBuilderインタフェースには、それぞれJsonObject型およびJsonArray型のモデルを作成するメソッドがあります。

これらのオブジェクト・モデルは、javax.json.JsonReaderインタフェースを使用して入力ソースから作成することもできます。同様に、これらのオブジェクト・モデルは、javax.jsonJsonWriterインタフェースを使用して出力ソースに書き込むことができます。

次の各項では、オブジェクト・モデルAPIの使用例を示します。

JSONデータからのオブジェクト・モデルの作成

次の例では、テキスト・ファイル内のJSONデータからオブジェクト・モデルを作成する方法を示します。

import java.io.FileReader;
import javax.json.Json;
import javax.json.JsonReader;
import javax.json.JsonStructure;
...
JsonReader reader = Json.createReader(new FileReader("jsondata.txt"));
JsonStructure jsonst = reader.read();

オブジェクト参照jsonstは、ファイルの内容に応じてJsonObject型またはJsonArray型のいずれかになります。JsonObjectおよびJsonArrayJsonStructureのサブタイプです。この参照はツリーの最上位を表したもので、ツリーの参照に使用したり、ストリームにJSONデータとして書き込むことができます。

アプリケーション・コードからのオブジェクト・モデルの作成

次の例では、アプリケーション・コードからオブジェクト・モデルを作成する方法を示します。

import javax.json.Json;
import javax.json.JsonObject;
...
JsonObject model = Json.createObjectBuilder()
   .add("firstName", "Duke")
   .add("lastName", "Java")
   .add("age", 18)
   .add("streetAddress", "100 Internet Dr")
   .add("city", "JavaTown")
   .add("state", "JA")
   .add("postalCode", "12345")
   .add("phoneNumbers", Json.createArrayBuilder()
      .add(Json.createObjectBuilder()
         .add("type", "mobile")
         .add("number", "111-111-1111"))
      .add(Json.createObjectBuilder()
         .add("type", "home")
         .add("number", "222-222-2222")))
   .build();

オブジェクト参照モデルはツリーの最上位を表したもので、addメソッドの呼出しをネストして作成し、buildメソッドを呼び出してビルドします。javax.json.JsonObjectBuilderインタフェースには、次のaddメソッドが含まれています。

JsonObjectBuilder add(String name, BigDecimal value)
JsonObjectBuilder add(String name, BigInteger value)
JsonObjectBuilder add(String name, boolean value)
JsonObjectBuilder add(String name, double value)
JsonObjectBuilder add(String name, int value)
JsonObjectBuilder add(String name, JsonArrayBuilder builder)
JsonObjectBuilder add(String name, JsonObjectBuilder builder)
JsonObjectBuilder add(String name, JsonValue value)
JsonObjectBuilder add(String name, long value)
JsonObjectBuilder add(String name, String value)
JsonObjectBuilder addNull(String name)

javax.json.JsonArrayBuilderインタフェースにも同様のaddメソッドが含まれていますが、name (key)パラメータは使用できません。配列およびオブジェクトをネストするには、この例で示したように、JsonArrayBuilderの新規オブジェクトまたはJsonObjectBuilderの新規オブジェクトを対応するaddメソッドに渡します。

生成されるツリーは、JSON構文で表したJSONデータです。

オブジェクト・モデルの参照

次の例では、オブジェクト・モデルを参照する簡単な方法を示します。

import javax.json.JsonValue;
import javax.json.JsonObject;
import javax.json.JsonArray;
import javax.json.JsonNumber;
import javax.json.JsonString;
...
public static void navigateTree(JsonValue tree, String key) {
   if (key != null)
      System.out.print("Key " + key + ": ");
   switch(tree.getValueType()) {
      case OBJECT:
         System.out.println("OBJECT");
         JsonObject object = (JsonObject) tree;
         for (String name : object.keySet())
            navigateTree(object.get(name), name);
         break;
      case ARRAY:
         System.out.println("ARRAY");
         JsonArray array = (JsonArray) tree;
         for (JsonValue val : array)
            navigateTree(val, null);
         break;
      case STRING:
         JsonString st = (JsonString) tree;
         System.out.println("STRING " + st.getString());
         break;
      case NUMBER:
         JsonNumber num = (JsonNumber) tree;
         System.out.println("NUMBER " + num.toString());
         break;
      case TRUE:
      case FALSE:
      case NULL:
         System.out.println(tree.getValueType().toString());
         break;
   }
}

navigateTreeメソッドは、「JSONデータからのオブジェクト・モデルの作成」および「アプリケーション・コードからのオブジェクト・モデルの作成」で示したモデルで使用できます。

navigateTree(model, null);

navigateTreeメソッドは2つの引数(JSON要素とキー)を取ります。キーは、オブジェクト内のキー/値のペアを出力する場合にのみ使用します。ツリー内の要素は、JsonValue型で表します。要素がオブジェクトまたは配列の場合、オブジェクトまたは配列に格納されている各要素に対して、このメソッドの新規呼出しが行われます。要素が値の場合は、標準出力に表示されます。

JsonValue.getValueTypeメソッドは、要素がオブジェクト、配列または値のいずれであるかを識別します。オブジェクトの場合、JsonObject.keySetメソッドはオブジェクトのキーが含まれる文字列セットを返し、JsonObject.get(String name)メソッドはキーがnameである要素の値を返します。配列の場合は、JsonArrayList<JsonValue>インタフェースが実装されます。この例で示したように、JsonObject.keySetによって返されたSet<String>インスタンス、およびJsonArrayのインスタンスには拡張forループを使用できます。

「アプリケーション・コードからのオブジェクト・モデルの作成」で示したモデルでnavigateTreeメソッドを実行すると、次の出力が生成されます。

OBJECT
Key firstName: STRING Duke
Key lastName: STRING Java
Key age: NUMBER 18
Key streetAddress: STRING 100 Internet Dr
Key city: STRING JavaTown
Key state: STRING JA
Key postalCode: STRING 12345
Key phoneNumbers: ARRAY
OBJECT
Key type: STRING mobile
Key number: STRING 111-111-1111
OBJECT
Key type: STRING home
Key number: STRING 222-222-2222

ストリームへのオブジェクト・モデルの書込み

「JSONデータからのオブジェクト・モデルの作成」および「アプリケーション・コードからのオブジェクト・モデルの作成」で作成したオブジェクト・モデルは、次に示すように、javax.json.JsonWriterインタフェースを使用してストリームに書き込むことができます。

import java.io.StringWriter;
import javax.json.JsonWriter;
...
StringWriter stWriter = new StringWriter();
JsonWriter jsonWriter = Json.createWriter(stWriter);
jsonWriter.writeObject(model);
jsonWriter.close();
 
String jsonData = stWriter.toString();
System.out.println(jsonData);
 
The Json.createWriter method takes an output stream as a parameter. The JsonWriter.writeObject method writes the object to the stream. The JsonWriter.close method closes the underlying output stream.
 
The following example uses try-with-resources to close the JSON writer automatically:
 
StringWriter stWriter = new StringWriter();
try (JsonWriter jsonWriter = Json.createWriter(stWriter)) {
   jsonWriter.writeObject(model);
}
 
String jsonData = stWriter.toString();
System.out.println(jsonData);

ストリーミングAPI

ストリーミングAPIは、大量のJSONデータを効率的に処理できるように設計された、低レベルのAPIです。このAPIは次のインタフェースで構成されます。

インタフェース 説明
javax.json.stream.JsonParser
JSONをストリーミングで解析するメソッドが含まれます。

このインタフェースでは、プル解析プログラミング・モデルを使用して、JSONデータに対し前方/読取り専用アクセスを行うことができます。このモデルでは、アプリケーション・コードを使用して、パーサー・インタフェースでスレッドの制御やメソッドのコールを行い、パーサーを前方に移動したり、現在のパーサーの状態からJSONデータを取得したりできます。

javax.json.stream.JsonGenerator
JSONをストリーミングで出力ソースに書き込むメソッドが含まれます。

このインタフェースには、JSONを出力ソースに書き込むメソッドがあります。ジェネレータによって、名前/値ペアがJSONオブジェクトに、値がJSON配列に書き込まれます。


次の各項では、ストリーミングAPIの使用例を示します。

パーサーを使用したJSONデータの読取り

ストリーミングAPIは、JSONテキストを解析する上で、最も効率的な方法です。次の例では、JsonParserオブジェクトの作成方法およびイベントを使用してJSONデータを解析する方法を示します。

import javax.json.Json;
import javax.json.stream.JsonParser;
...
JsonParser parser = Json.createParser(new StringReader(jsonData));
while (parser.hasNext()) {
   JsonParser.Event event = parser.next();
   switch(event) {
      case START_ARRAY:
      case END_ARRAY:
      case START_OBJECT:
      case END_OBJECT:
      case VALUE_FALSE:
      case VALUE_NULL:
      case VALUE_TRUE:
         System.out.println(event.toString());
         break;
      case KEY_NAME:
         System.out.print(event.toString() + " " +
                          parser.getString() + " - ");
         break;
      case VALUE_STRING:
      case VALUE_NUMBER:
         System.out.println(event.toString() + " " +
                            parser.getString());
         break;
   }
}

この例は、次の3つのステップで構成されます。

  1. Json.createParser静的メソッドを呼び出して、パーサー・インスタンスを取得します。

  2. JsonParser.hasNextメソッドおよびJsonParser.nextメソッドを使用して、パーサー・イベントを繰り返します。

  3. 要素ごとにローカル処理を実行します。

この例は、パーサーから生成される可能性のある10個のイベント・タイプを示しています。パーサーのnextメソッドで次のイベントに進みます。

KEY_NAMEVALUE_STRINGおよびVALUE_NUMBERの各イベント・タイプでは、JsonParser.getStringメソッドを呼び出して、要素の内容を取得できます。

VALUE_NUMBERイベントでは、次のメソッドを使用することもできます。

START_OBJECT
KEY_NAME firstName - VALUE_STRING Duke
KEY_NAME lastName - VALUE_STRING Java
KEY_NAME age - VALUE_NUMBER 18
KEY_NAME streetAddress - VALUE_STRING 100 Internet Dr
KEY_NAME city - VALUE_STRING JavaTown
KEY_NAME state - VALUE_STRING JA
KEY_NAME postalCode - VALUE_STRING 12345
KEY_NAME phoneNumbers - START_ARRAY
START_OBJECT
KEY_NAME type - VALUE_STRING mobile
KEY_NAME number - VALUE_STRING 111-111-1111
END_OBJECT
START_OBJECT
KEY_NAME type - VALUE_STRING home
KEY_NAME number - VALUE_STRING 222-222-2222
END_OBJECT
END_ARRAY
END_OBJECT

ジェネレータを使用したJSONデータの書込み

次の例では、ストリーミングAPIを使用してJSONデータをファイルに書き込む方法を示します。

FileWriter writer = new FileWriter("test.txt");
JsonGenerator gen = Json.createGenerator(writer);
gen.writeStartObject()
   .write("firstName", "Duke")
   .write("lastName", "Java")
   .write("age", 18)
   .write("streetAddress", "100 Internet Dr")
   .write("city", "JavaTown")
   .write("state", "JA")
   .write("postalCode", "12345")
   .writeStartArray("phoneNumbers")
      .writeStartObject()
         .write("type", "mobile")
         .write("number", "111-111-1111")
      .writeEnd()
      .writeStartObject()
         .write("type", "home")
         .write("number", "222-222-2222")
      .writeEnd()
   .writeEnd()
.writeEnd();
gen.close();

この例では、ライター・ストリームまたは出力ストリームをパラメータとして取るJson.createGenerator静的メソッドを呼び出して、JSONジェネレータを取得します。例では、writewriteStartArraywriteStartObjectおよびwriteEndの各メソッドの呼出しをネストして、JSONデータをtest.txtファイルに書き込みます。JsonGenerator.closeメソッドで、内部のライター・ストリームまたは出力ストリームを閉じます。