目次


Jackson JSON プロセッサーと Apache Wink を組み合わせて使う

JAX-RS と Ajax を簡単に統合する

Comments

はじめに

Apache Wink は JAX-RS 仕様のデファクト実装の 1 つになりつつあります。JSON 同期のためのデフォルトのプロバイダーである JSON.org と Jettison には、いくつかの問題があります。例えば配列の表現に問題があったり、戻り型が制限されていたりするため、JAX-RS サービスのコーディングや、JAX-RS サービスのクライアントとしての Ajax アプリケーションのコーディングは簡単ではありません。

この記事では、JSON プロバイダーとして Jackson を使うように既存の Apache Wink 対応 Web アプリケーションを構成する方法を概説します。Jackson 対応の簡単な JAX-RS Web サービスのサンプル・コードを使いながら、Jackson プロバイダーの長所について学びましょう。

Apache Wink にパッケージ化された JSON プロバイダー

Apache Wink の標準ディストリビューションには、JSON.org 実装と Jettison 実装という 2 つの JSON プロバイダーがパッケージ化されています。この 2 つのプロバイダーにはどちらも問題があるため Wink サービスと Ajax アプリケーションとの統合は簡単ではありません。どちらのプロバイダーも、Java の List を JSON に直接シリアライズして戻り型として返すことはできません。JAXB の要件からラッパーとして XML 要素が必要だからです。また 2 つのプロバイダーには、他にも下記のような問題があります。

JSON.org
JSON.org プロバイダーによって配列をシリアライズした結果は予測可能ですが、そのシリアライズした結果を Ajax で操作しようとすると、望んだような動作をしてくれません。JSON.org では、可変サイズの配列を表す場合、以下のように要素数に応じて表現方法が異なるからです。
  • 2 またはそれ以上 : 配列を「正しく」シリアライズして表現します。例えば object : { array : ["element1", "element2"] } など。
  • 1 : 配列を展開して表現します。例えば object : { array : "element1" } など。
  • 0 : 配列を完全に削除します。例えば object : { } など。

JavaScript でさまざまな構造でのコーディングを許容すると、非常に複雑になって望ましくないことは明らかです。

Jettison
Jettison は Badgerfish 規則を使って JSON を生成するため、生成された構造を JavaScript オブジェクトに変換すると、ナビゲートしにくい構造になります。

Jackson

Jackson のコアは JSON プロセッサーであり、このプロセッサーを使って Java オブジェクトの JSON 表現の生成と解析の両方を行います。また JAX-RS 実装の JSON シリアライズ・プロバイダーとして Jackson を構成することもできます。

JAX-RS 実装の JSON シリアライズ・プロバイダーとしての Jackson には、JSON.org や Jettison に比べて以下のような長所があります。

表 1. Jackson の長所
長所説明
ネイティブで List をシリアライズ可能Jackson はサービスから直接ストリング・オブジェクトの List を返すことができ、ラッパーとしての XML 要素は必要ありません。
配列処理Jackson には、結果を予測できる優れたシリアライズ機能があります。
速度他のプロバイダーよりも明らかに高速です。
ライセンスApache ライセンス 2.0 は広く理解されています。このライセンスを使用するコンポーネントは商用ソフトウェア製品にも無料ソフトウェア製品にも使われています。

Jackson 用に Apache Wink を構成する

この記事のサンプルの説明では、以下のことを前提にしています。

  • JAX-RS プロバイダーとして Apache Wink を使用するように構成された既存の動的 Web プロジェクトがある。
  • web.xml ファイルの中で、JAX-RS アプリケーションを使うように Wink サーブレット (org.apache.wink.server.internal.servlet.RestServlet) が構成されている (リスト 1)。
リスト 1. Wink サーブレットの web.xml のスニペット
<servlet>
  <servlet-name>WinkServlet</servlet-name>
  <servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.ibm.developerworks.winkJackson.WinkApplication</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>WinkServlet</servlet-name>
  <url-pattern>/services/*</url-pattern>
</servlet-mapping>

Jackson ライブラリーをダウンロードしてインストールする

Jackson の Web サイトから Jackson プロバイダーの最新バージョンをダウンロードします (「参考文献」のリンクを参照)。この記事の執筆時点で、Apache Wink で Jackson を使うために必要なライブラリーを一括ダウンロードできるリソースは提供されていません。ここでは、ASL バージョンまたは LGPL バージョンいずれかの JAR ファイル (下記) が必要です。

  • core-(asl/lgpl): Jackson のコア関数
  • mapper-(asl/lgpl): POJO と JSON とのシリアライズ用
  • jax-rs: Wink と Jackson とのインターフェース
  • jax-xc: JAXB アノテーションとの後方互換用

これらの JAR ファイルは Web プロジェクトのクラスパス上になければなりません。そうするために最も簡単な方法は、これらの JAR ファイルを WEB-INF/lib ディレクトリーに配置することです。(皆さんの Apache Wink の JAR ファイルは、おそらく既にこのディレクトリー上にあります。)

Jackson プロバイダーを使って JSON シリアライズを行うように Apache Wink を構成する

この時点で Jackson JSON プロバイダーは Web アプリケーションの一部としてロードされていますが、まだ Apache Wink に対して、JSON へのシリアライズに Jackson プロバイダーを使うように指示してありません。

Wink サーブレットの構成を調整し、このアプリケーションが Jackson プロバイダーをロードするようにします (リスト 2)。

リスト 2. WinkApplication.java のサンプル
package com.ibm.developerworks.winkJackson;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

// Jackson imports
import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;

public class WinkApplication extends Application {

  /**
   * Get the list of service classes provided by this JAX-RS application
   */
  @Override
  public Set<Class<?>> getClasses() {
    Set<Class<?>> serviceClasses = new HashSet<Class<?>>();
    serviceClasses.add(HelloWorlds.class);
    return serviceClasses;
  }
  
  @Override
  public Set<Object> getSingletons() {
    Set<Object> s = new HashSet<Object>();
    
    // Register the Jackson provider for JSON
    
    // Make (de)serializer use a subset of JAXB and (afterwards) Jackson annotations
    // See http://wiki.fasterxml.com/JacksonJAXBAnnotations for more information
    ObjectMapper mapper = new ObjectMapper();
    AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
    AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
    AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
    mapper.getDeserializationConfig().setAnnotationIntrospector(pair);
    mapper.getSerializationConfig().setAnnotationIntrospector(pair);
    
    // Set up the provider
    JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
    jaxbProvider.setMapper(mapper);
    
    s.add(jaxbProvider);
    return s;
  }

}

List<?> を直接シリアライズする

Jackson を使うと Java の List を容易に List の関数から返すことができ、JAXB 用のラッパーとしての XML 要素が必要ありません。リスト 3 はその一例を示しています。

リスト 3. HelloWorlds.java
package com.ibm.developerworks.winkJackson;

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("helloworlds")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorlds {
  
  @GET
  public List<String> helloWorlds() {
    return Arrays.asList(new String [] {"Hello Earth!",  "Hello Mars!" });
  }
	
}

まとめ

JAX-RS 仕様の実装として Apache Wink が使われることが多くなっています。JSON 同期のデフォルト・プロバイダーは JSON.org と Jettison ですが、この 2 つにはいくつかの問題があります。この記事では、JSON プロバイダーとして Jackson を使うように既存の Apache Wink 対応 Web アプリケーションを構成する方法について学びました。また Jackson 対応の簡単な JAX-RS Web サービスのサンプル・コードを使用して、Jackson プロバイダーの長所を示しました。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Java technology, SOA and web services
ArticleID=491817
ArticleTitle=Jackson JSON プロセッサーと Apache Wink を組み合わせて使う
publish-date=04202010