JAX-RS(Jersey)を使ってみる
JaveEE6に対応しているGlassfish 3.0を使う方が手っ取り早いとは思いますが、、サーブレットコンテナとしてTomcat6.0を使った環境でJAX-RSを使ってみます。
JAX-RSの実装としては、JavaによるRESTfulシステム構築では、Jersey, Apache CXF, JBoss RESTEasyなんかが紹介されています。CXFはJAX-WSも含んでいて大きそうなので、今回は参照実装であるJersey 1.5を使ってみます。前提としてMavenを使ったWebアプリケーションのプロジェクトがあるとします。
pom.xmlでの依存ライブラリの追加
pom.xmlにrepositoryとdepenencyを追加します。jersey-jsonはJSONを使用する場合に追加します。Jacksonが使われるようです。
<repositories> <!-- 省略 --> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> <layout>default</layout> </repository> </repositories> <dependencies> <!-- 省略 --> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.5</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.5</version> </dependency> <dependencies>
リソースの作成
とりあえず簡単なリソースクラスを作成します。/helloというパスにGETメソッドでアクセスすると"Hello World"というテキストを返します。
package com.azuki3.sample.jaxrs.resources; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/hello") public class HelloWorldResource { @GET @Produces(MediaType.TEXT_PLAIN) public String sayHello(){ return "Hello World"; } }
Applicationクラスの作成
ディプロイ対象となるリソースを記述したApplicationクラスを作成します。
package com.azuki3.sample.jaxrs.config; import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; import com.azuki3.sample.jaxrs.resources.HelloWorldResource; public class MyApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> s = new HashSet<Class<?>>(); s.add(HelloWorldResource.class); return s; } }
web.xmlへのサーブレットの追加
この辺はJaveEE6対応のコンテナだと不要ですが、今回は、JaveEE6/JAX-RSに未対応のTomcat6.0なので、web.xmlにサーブレットの記述を追加します。
<servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.azuki3.sample.jaxrs.config.MyApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
JerseyはデフォルトではScanningResourceConfigというクラスがリソースをスキャンして登録してくれるようです。そのためApplicationクラスを登録しなくてもリソースにアクセスできます。
または、リソースの存在するパッケージを指定することも可能で、その場合にはinit-paramで以下のようにパッケージを指定します。
<param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.azuki3.sample.jaxrs.resources</param-value>
リソースにアクセスする
Tomcatを起動してブラウザから、http://localhost:8080/jaxrs/rest/hello にアクセスすると*1、"Hello World"と表示されます。
JSONを使用する
レスポンスをJSON形式にしてみます。リソースとして連絡先を表すContactというクラスを作成します。@XmlRootElementアノテーションを付けておきます。
package com.azuki3.sample.jaxrs.entity; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Contact { private Integer id; private String name; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
このリソースにアクセスするためのContactResourceクラスを作成します。@Producesアノテーションで。MediaType.APPLICATION_JSONを指定します。
package com.azuki3.sample.jaxrs.resources; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import com.azuki3.sample.jaxrs.entity.Contact; import com.azuki3.sample.jaxrs.service.AbstractService; import com.sun.jersey.api.NotFoundException; @Path("/contacts") public class ContactResources{ private static Contact[] contacts = { createContact(1, "foo", "Tokyo"), createContact(2, "bar", "Osaka"), createContact(3, "baz", "Naogya") }; @GET @Produces({MediaType.APPLICATION_JSON}) public Contact[] getContacts() { return contacts; } @Path("{id}") @GET @Produces({MediaType.APPLICATION_JSON}) public Contact getContact(@PathParam("id")Integer id) { if(id > contacts.length){ throw new NotFoundException("No such Contact."); } return contacts[id-1]; } private static Contact createContact(Integer id, String name, String address){ Contact contact = new Contact(); contact.setId(id); contact.setName(name); contact.setAddress(address); return contact; } }
getContactで指定されたidのContactが存在しない場合に、nullを返すとステータスが204(No content)になり、リソースは存在するが内容がないということになってしまうので、404を返すためにNotFoundExceptionをスローしています。ちなみにidに整数以外を指定した場合も404になります(idの型が違うのでContactResource自体が呼び出されません)。
MyApplicationクラスにContactResourcesを追加します。
これで、http://localhost:8080/jaxrs/rest/contacts にアクセスすると以下のようにすべてのContactがJSONで返されます。
{"contact":[{"address":"Tokyo","id":"1","name":"foo"},{"address":"Osaka","id":"2","name":"bar"},{"address":"Naogya","id":"3","name":"baz"}]}
http://localhost:8080/jaxrs/rest/contacts/1 にアクセスすると以下のようにid=1のContactがJSONで返されます。
{"address":"Tokyo","id":"1","name":"foo"}
まとめ
今回はさわり程度で、、DBへのアクセスやリソースの追加・更新を行っていないので非常に簡単でした。
次はSeasar2との連携させてS2JDBCでDBにアクセスする方法などを試してみたいと思います。
参考
以下のサイトを参考にしました。
- 作者: Bill Burke,arton,菅野良二
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/08/23
- メディア: 大型本
- 購入: 28人 クリック: 780回
- この商品を含むブログ (35件) を見る
- 作者: Leonard Richardson,Sam Ruby,山本陽平,株式会社クイープ
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2007/12/21
- メディア: 単行本
- 購入: 25人 クリック: 809回
- この商品を含むブログ (168件) を見る
*1:"jaxrs"はコンテキストパスです。