hakobera's blog

技術メモ。たまに雑談

Glassfish の JAX-RS の JSON プロセッサの実装がイけてないのでどうにかする

GlassfishJAX-RS (= Jersey 1.1.5) の JSON プロセッサのリスト/配列の扱いが相当イけてない。具体的には、Jackson JSON プロセッサーと Apache Wink を組み合わせて使う に書いてある JSON.org の実装と同じ動きをする。

JSON.org プロバイダーによって配列をシリアライズした結果は予測可能ですが、そのシリアライズした結果を Ajax で操作しようとすると、望んだような動作をしてくれません。JSON.org では、可変サイズの配列を表す場合、以下のように要素数に応じて表現方法が異なるからです。

2 またはそれ以上 : 配列を「正しく」シリアライズして表現します。例えば object : { array : ["element1", "element2"] } など。
1 : 配列を展開して表現します。例えば object : { array : "element1" } など。
0 : 配列を完全に削除します。例えば object : { } など。

これだと、クライアント側で受け取る型が変わってしまうので、クライアント再度の Javascript が上手く動かないことが多い。また、これ以外にも Entity のプロパティの型が Integer、Boolean など JSON で扱える型であっても、全て文字列に変換してしまったりと、色々と余計なことをしてくれる。

解決策としてはエントリの最初で紹介した記事で紹介している Jackson というライブラリを利用すれば良い。ただし、記事中の方法は Jersey に依存しているので、今回は汎用的に使えるOracle Technology Network for Java Developersのサービスプロバイダの仕組みを利用した方法を利用する。

Jackson をダウンロードして、クラスパス通す。

maven を使う場合は、以下の2つを依存関係に追加する。


	org.codehaus.jackson
	jackson-jaxrs
	1.5.6


	org.codehaus.jackson
	jackson-xc
	1.5.6

プロバイダ構成ファイルの作成

クラスパス上に META-INF/services というフォルダをつくり、そこに javax.ws.rs.ext.MessageBodyReader という名前のファイルを作る。ファイルをテキストエディタで開き、以下の1行を記述する。

org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider

以上で、JAX-RS の JSON プロセッサとして、Jackson が使用されるようになる。

ただ、Jackson も日付がlong値(= java.util.Date#getTime()の戻り値)で返ってくる(Glassfishデフォルトは ISO 8601形式の文字列)という点が少し微妙。でも、配列と型の扱いの方が重要なので、現時点では JAX-RS の JSON プロセッサには Jackson がお勧め。

java.sql.Date の件といい型変換の部分で躓くことが多いのが難点だと思うけど、それさえ乗り越えれば、JAX-RS はとても使いやすいので、もっとみんな使うべきだと思う。