読者です 読者をやめる 読者になる 読者になる

JerseyのJSONサポート

引き続きJerseyについて調査しています。JerseyでレスポンスとしてJavaのオブジェクトをJSONに変換する場合には、いくつか方法があります。

  1. POJOを直接変換する
  2. JAXB経由で変換する
  3. JSONObjectを生成する

Jersey 1.5 User Guide - Chapter 5. JSON Support
この前で試した方法(@XmlRootElementアノテーションをエンティティクラスに付加する)では、2番目のJAXB経由が使われます。3番目はJSONを表すオブジェクト(JSONObject)を組み立てる方法です。
1番目の方法を使用する場合には、web.xmlで、サーブレットのinit-paramに以下の記述を追加します。

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

1,2で生成されるJSONは少し違いがあります。概ねJAXBでのマーシャリングの設定のデフォルトによる影響だと思いますが、例えばListや配列を変換した場合には、以下のよう、エレメント名(XmlRootElementアノテーションのname指定)がキーで、配列が値として設定されたにオブジェクトが生成されます。1番目の方法では配列のみです。

{"contact":[{"address":"Tokyo","id":"1","name":"foo"},{"address":"Osaka","id":"2","name":"bar"},{"address":"Naogya","id":"3","name":"baz"}]}

あとはデフォルトでnullが出力されないとか。おそらく@XmlElementアノテーションで、nillable=trueが必要。

この設定は、空のListをJAXB経由でJSONにして出力するとレスポンスが"null"という文字列になる原因を調査していて知りました。
リソースのリストを取得する際、常に全件を取得するのは非効率なのでクライアントサイドでページングをすることになると思います。その場合、件数が必要になるので、直接リストや配列を返すのではなく件数や結果のリストを含むオブジェクトを返すだろうとは思うのですが。