本格派エンジニアの工具箱

第27回 JSONデータを扱うためのJavaライブラリ「Jackson Java JSON-processor」

この記事を読むのに必要な時間:およそ 4 分

「Jackson Java JSON-processor」とは

近年のWebアプリケーション開発では,JSONが必須の技術になっています。クライアントサイドで利用されるJavaScriptで容易に扱えることから,Webサーバとのデータ交換のためのフォーマットとして広く利用されているからです。Javaアプリケーションも例外ではなく,次期Java EE仕様であるJava EE 7JSR 343として仕様策定中)にもJSONを扱うためのAPIが標準で取り込まれる見込みになっています。

それに伴い,Java用のJSON APIの標準仕様についても,JSR 353として標準化プロセスに入っています。その他にも,すでにJavaでJSONを扱うための様々なライブラリが存在しています。中でもJackson Java JSON-processorgoogle-jsonはJSR 353にも既存実装として名前が挙がっており,標準仕様へ与える影響も大きいと思われます。

今回は,そのうちの「Jackson Java JSON-processor」⁠以下,Jackcon)の使い方を紹介します。JacksonはLGPL 2.1またはApache License 2.0のもとで開発されているオープンソースのJSONライブラリです。JacksonではJavaプログラムからJSONデータを扱うために次の3種類の方法が提供されています。

  • ストーミングAPIによるJSONデータへのアクセス(XMLのStAXに相当)
  • ツリーモデルでのJSONデータへのアクセス(XMLのDOMに相当)
  • JSONオブジェクトとJavaオブジェクトのバインディング

さらに,データバインディングには,JavaのMapやList,Stringなど基本的なオブジェクトへのバインディングと,汎用的なJava Beanオブジェクトへのバインディングの2種類が用意されています。

ストリーミングAPIでJSONデータを読み込む

まずはストリーミングAPIを使ってJSONデータの読み込みを行ってみましょう。ストリーミングAPIは,XMLにおけるStAX(Streaming API for XML)と同様に,JSONデータに対してストリーミング形式でアクセスするためのAPIです。JacksonのストリーミングAPIでは,JSON形式のファイルやストリームの先頭から,トークン単位でデータを取り出すことができます。そのためにはまず,パーサーの機能を持ったJsonParserオブジェクトを作成しましょう。これはJsonFactoryクラスを使って次のように行います。

// JsonFactoryの生成
JsonFactory factory = new JsonFactory();
// JsonParserの取得
JsonParser parser = factory.createJsonParser(new File("sample.json"));

この例ではcreateJsonParser()メソッドに読み込み元となるJSONファイルのFileインスタンスを渡していますが,その他に入力ストリームやURLのインスタンス,JSON形式の文字列やバイト配列を指定することもできます。

作成したJsonParserに対してnextToken()メソッドを実行すると,現在位置の次のトークンがJsonTokenオブジェクトとして取得できます。トークンには次のような種類があります。これはJsonTokenクラスに列挙型として定義されています。

  • START_ARRAY - 配列の開始('[')
  • END_ARRAY - 配列の終了(']')
  • START_OBJECT - オブジェクトの開始('{')
  • END_OBJECT - オブジェクトの終了('}')
  • FIELD_NAME - フィールド名
  • VALUE_EMBEDDED_OBJECT - 組み込みオブジェクト形式の値
  • VALUE_FALSE - "false"値
  • VALUE_TRUE - "true"値
  • VALUE_NULL - nulla値
  • VALUE_NUMBER_FLOAT - float型の値
  • VALUE_NUMBER_INT - int型の値
  • VALUE_STRING - 文字列形式の値

たとえば,次のようなJSONデータがあったとすると,JsonParserによってのようなトークンに分解され,netxToken()メソッドで1つずつ取り出すことができます。

[ { "name" : { "first" : "太郎", "last" : "技評" } } ]

図1 JsonParserによるトークンへの分解

図1 JsonParserによるトークンへの分解

現在位置のトークンのデータを取り出すためには,JsonParserのgetXXXX()形式のメソッドを使います。例えばgetText()メソッドでは現在のトークンのテキストを取得することができます。つまり,基本的にはgetNext()で取得したトークンが目的の種類のものであったら,getXXXX()メソッドでその中身を取り出すという流れで処理を進めていきます。

以上を踏まえて,次のようなJSONデータについて考えてみましょう。

[{
  "name" : { "first" : "太郎", "last" : "技評" }, 
  "mail" : "taro@example.jp", 
  "todo" : { "work" : "hogehoge", "limit" : "2012/02/13" }
}, 
{
  "name" : { "first" : "次郎", "last" : "技術" }, 
  "mail" : "jiro@example.jp", 
  "todo" : { "work" : "hogehoge", "limit" : "2012/02/15" }
}, 
{
  "name" : { "first" : "花子", "last" : "評論" }, 
  "mail" : "hanako@example.jp", 
  "todo" : { "work" : "hogepiyo", "limit" : "2012/02/28" }
}]

次のコードは,このJSONの内容を一覧表示する例です。

// JsonFactoryの生成
JsonFactory factory = new JsonFactory();
// JsonParserの取得
JsonParser parser = factory.createJsonParser(new File("sample.json"));
      
// 配列の処理
if (parser.nextToken() == JsonToken.START_ARRAY) {
    while (parser.nextToken() != JsonToken.END_ARRAY) {
	// 各オブジェクトの処理
	if (parser.getCurrentToken() == JsonToken.START_OBJECT) {
            while (parser.nextToken() != JsonToken.END_OBJECT) {
		String name = parser.getCurrentName();
		parser.nextToken();
		// "name"フィールド
		if ("name".equals(name)) {
		    System.out.println(name + ": ");
		    while (parser.nextToken() != JsonToken.END_OBJECT) {
			if (parser.getCurrentToken() == JsonToken.FIELD_NAME) {
			    System.out.print("    " + parser.getText() + ": ");
			} else if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
			    System.out.println(parser.getText());
			}
		    }
		}
		// "mail"フィールド
		else if ("mail".equals(name)) {
		    System.out.println(name + ": " + parser.getText());
		} 
		else {
		    parser.skipChildren();
		}
            }
	}
	else {
            parser.skipChildren();
	}        
    }
}
else {
    parser.skipChildren();
}

配列の開始と終了,オブジェクトの開始と終了を基準に,その中身のフィールド名と値を順番に取得しして表示しています。現在のトークンのフィールド名はgetCurrentName()メソッドで取得できるので,これを元にして"name"か"mail"かを判断しています。

このプログラムの出力結果は次のようになります。

name: 
    first: 太郎
    last: 技評
mail: taro@example.jp
name: 
    first: 次郎
    last: 技術
mail: jiro@example.jp
name: 
    first: 花子
    last: 評論
mail: hanako@example.jp

著者プロフィール

杉山貴章(すぎやまたかあき)

ONGS Inc.所属のプログラマ兼テクニカルライター。雑誌,書籍,Webメディアで多数の著作をもつ。

著書

コメント

コメントの記入