Implementing RESTful Web Services in Java

JavaでのRESTfulウェブサービス(JSR-311)実装のJersey(https://jersey.dev.java.net/)の技術TIPS。

JAX-RS と Jersey


JAX-RSは、JavaでRESTfulウェブサービスを構築するための標準化された
annotationやインターフェースAPIを提供します。
まだ完全なものではないようですが最終系は、Java EE 6の一部になるようです。
JAX-RSの詳細な情報は、jsr311 project(https://jsr311.dev.java.net/)で得る事ができます。


Jerseyプロジェクトからダウンロードすると、いくつかのサンプルが見れます。

技術TIPSで見たのは、Bookmark Application。

データがJSON
JAX-RS APIを使い以下のようなJSONデータを返します(ブックマーク保存時)

{"sdesc":"test desc","userid":"testuserid","uri":
   "http://java.sun.com","ldesc":"long test description"}

examples/Bookmark配下に以下のResource。
・UsersResource
・UserResource
・BookmarksResource
・BookmarkResource

それぞれのResourceとURIとHTTPメソッド

Resource URI Path HTTP Methods
UsersResource /users GET
UserResource /users/{userid} GET, PUT, DELETE
BookmarksResource /users/{userid}/bookmarks GET, POST
BookmarkResource /users/{userid}/bookmarks/{bmid} GET, PUT, DELETE

JAX-RSの基本的な理解の為に、UsersResourceとUserResourceの2つのResourceについて紹介されていました。

UsersResource

@UriTemplate("/users/")

   public class UsersResource {
     
       @HttpContext UriInfo uriInfo;    

       @PersistenceUnit(unitName = "BookmarkPU")
       EntityManagerFactory emf;

       /** Creates a new instance of Users */
       public UsersResource() {
       }
    
       public List<UserEntity> getUsers() {
           return emf.createEntityManager().createQuery(
                  "SELECT u from UserEntity u").getResultList();
       }
    
       @UriTemplate("{userid}/")
       public UserResource getUser(@UriParam("userid") 
              String userid) {
           return new UserResource(
                  uriInfo, emf.createEntityManager(), userid);
       }

       @HttpMethod("GET")
       @ProduceMime("application/json")
       public JSONArray getUsersAsJsonArray() {
           JSONArray uriArray = new JSONArray();
           UriBuilder ub = null;
           for (UserEntity userEntity : getUsers()) {
               ub = (ub == null) ? uriInfo.getBuilder() : ub.clone();
               URI userUri = ub.path(userEntity.getUserid()).build();
               uriArray.put(userUri.toString());
           }
           return uriArray;
       }
   }

ここで注目すべきは2つのJSR311アノテーション
@HttpMethod("GET")と@ProduceMime("application/json")です。

UserResource

   @HttpMethod("GET")
   @ProduceMime("application/json")
   public JSONObject getUser() throws JSONException {
       if (null == userEntity) {
           throw new NotFoundException("userid " + userid + "does not exist!");
       }
       return new JSONObject()
           .put("userid", userEntity.getUserid())
           .put("username", userEntity.getUsername())
           .put("email", userEntity.getEmail())
           .put("password", userEntity.getPassword())
           .put("bookmarks", uriInfo.getBuilder()
           .path("bookmarks").build());
    } 

これを見て、ソースから直感的に想像がつくという印象を受けました。
UsersResourceはJSONの配列を返し、UserResourceはJSONを返すのも分かり易いです。



この辺のサンプルは、NetBeansコマンドラインから確認出来ます。

前準備

1.GlassFish V2をダウンロード&インスコ
2.最新のJersey SNAPSHOTをダウンロード

NetBeans

1.NetBeans5.5.1をダウンロード&インスコ
2.NetBeansGlassFishを設定
3.Bookmarkプロジェクトを展開
4.Bookmarkプロジェクトをビルド&デプロイ

コマンドライン

1.AS_HOMEを設定
2.AS_HOME/lib/ant/bin/ant run-on-glassfishを実行


ブックマークアプリケーションをデプロイして動作確認にcurlを使用する方法がありました。
1.curlをダウンロード
2.ユーザ追加

curl -i --data "{\"userid\":\"techtip\",\"username\": 
    \"TechTip User\",\"email\":\"techtip@example.com\",
    \"password\":\"TEST\"}" -H Content-type:application/json -X 
    PUT http://localhost:8080/Bookmark/resources/users/techtip/

output

      HTTP/1.1 204 No Content
      X-Powered-By: Servlet/2.5
      Server: Sun Java System Application Server 9.1_01
      Date: Thu, 01 Nov 2007 14:31:53 GMT

3.ユーザリスト取得

curl -i -X GET http://localhost:8080/Bookmark/resources/users/

output

      HTTP/1.1 200 OK
      X-Powered-By: Servlet/2.5
      Server: Sun Java System Application Server 9.1_01
      Content-Type: application/json
      Transfer-Encoding: chunked
      Date: Thu, 01 Nov 2007 14:34:07 GMT

      ["http:\/\/localhost:8080\/Bookmark\/resources\/users\
      /techtip"]

4.ユーザ情報取得

curl -i -X GET http://localhost:8080/Bookmark/resources/users/techtip/

output

      HTTP/1.1 200 OK
      X-Powered-By: Servlet/2.5
      Server: Sun Java System Application Server 9.1_01
      Content-Type: application/json
      Transfer-Encoding: chunked
      Date: Thu, 01 Nov 2007 14:35:38 GMT

      {"userid":"techtip","username":"TechTip User",
      "email":"techtip@example.com","password":"TEST",
      "bookmarks":"http:\/\/localhost:8080\/Bookmark\/resources
      \/users\/techtip\/bookmarks"}


当分は、他にやることが山積みだけど
JavaでRESTful Web Serviceは自分自身経験がないので時間を作って弄ってみようと思います。

あとはこのTIPSからいくつかアイデアも浮かびました。