RESTEasyとjBPM

jBPMGWT-ConsoleをみてたらRESTEasyを使ってた。こちらがサイト。http://www.jboss.org/resteasy/
たしかに簡単そうだったのでミニマムで動かしてみた。ユーザガイドがついてるんだけど非常にわかりやすくてよかった。サクっと読めます。

RESTEasyの特徴は以下の通り。

JAX-RS実装
ポータブル
単体テスト用の組み込みサーバ付き
EJB/Springインテグレーション
ClientFramework付き(Commons-HttpClient依存)

細かいところではslf4jを利用してたり、RESTEasy独自仕様として@Formがあることかな。

@POST
@Path("/test")
public void post(@Form MyForm form) {...}

って感じ。
で、実際に動かすにあたってすることはいたって簡単で以下のステップでやった
1.依存ライブラリゲット. pomは以下の通り

 <repositories>
  <repository>
   <id>jboss</id>
   <url>http://repository.jboss.org/maven2</url>
  </repository>
  <repository>
   <id>google</id>
   <url>http://google-gson.googlecode.com/svn/mavenrepo</url>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
   <releases>
    <enabled>true</enabled>
   </releases>
  </repository>
 </repositories>
 <dependencies>
  <dependency>
   <groupId>org.jboss.resteasy</groupId>
   <artifactId>resteasy-jaxrs</artifactId>
   <version>1.0-beta-9</version>
  </dependency>
  <dependency>
   <groupId>com.google.code.gson</groupId>
   <artifactId>gson</artifactId>
   <version>1.2.3</version>
  </dependency>
 </dependencies>

jsonのコンバートはgsonを使ってみた。

2.web.xml修正

  <context-param>
   <param-name>javax.ws.rs.core.Application</param-name>
   <param-value>com.sample.SampleRestApplication</param-value>
  </context-param>

  <listener>
   <listener-class>
    org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
   </listener-class>
  </listener>

  <servlet>
   <servlet-name>Resteasy</servlet-name>
    <servlet-class>
     org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
   </servlet-class>
  </servlet>

  <servlet-mapping>
   <servlet-name>Resteasy</servlet-name>
   <url-pattern>/*</url-pattern>
  </servlet-mapping>

ListenerとServletをRESTEasyのものを指定。Applicationは今回用意するものをFQNで指定する。

3.サンプルApplicationクラスの用意
JAX-RS仕様ではApplicationを継承してユーザが固有のものを用意する。今回は以下の通り。

public class SampleRestApplication extends Application
{
  HashSet<Object> singletons = new HashSet<Object>();

  public SampleRestApplication()
  {
   singletons.add(new RainbowDrop());
  }

  @Override
  public Set<Class<?>> getClasses()
  {
   HashSet<Class<?>> set = new HashSet<Class<?>>();
   return set;
  }

  @Override
  public Set<Object> getSingletons()
  {
   return singletons;
  }
}

getClassesとgetSingletonsをオーバーライドするんだけどRESTEasyのソースをみるかぎりはgetClassに指定した場合に@Pathがついてればリクエスト毎のライフサイクルをもつリソースとして管理して、そうでない場合はProviderとして管理するっぽい。今回は空で(nullでもよいっぽい)getSingletonsで指定したリソースはsingletonで。今回の場合はRainbowDropというリソースクラスだけど。

4.リソース対象のクラスを用意
今回は以下の通りで用意

@Path("rainbowdrop")
public class RainbowDrop
{
  private List<Map<String, String>> items = new ArrayList<Map<String, String>>();
   
  @GET
  @Path("items")
  @Produces("application/json")
  public Response getItems()
  {
   return createJson();
  }

  @GET 
  @Path("items/new/{name}")
  @Produces("application/json")
  public Response newItem(
    @PathParam("name")
    String name)
  {
    Map<String, String> map = new HashMap<String, String>();
    map.put("name", name);
    items.add(map);
    return createJson();
  }

  private Response createJson() {
    Gson gson = new Gson();
    String json = gson.toJson(items);
    return Response.ok(json).type("application/json").build();
  }

}

5.ブラウザでまずはためす。
webアプリを起動させて
http://localhost:8080/resteasy-sample/rainbowdrop/items/new/red
http://localhost:8080/resteasy-sample/rainbowdrop/items/new/blue
でリソースを追加して
http://localhost:8080/resteasy-sample/rainbowdrop/items
で取得すると
[{"name":"red"},{"name":"blue"}]
と返ってきました。

RESTEasyにはEJB/Spring連携のexampleもついてるので敷居はかなり低いと思いました。めでたし、めでたし。