カタログページに関するサーバ側の風景

PetStoreのトップページからペットの種類を選んだ後は,ペットのカタログページが表示される。このカタログページは,Webブラウザに対する操作に反応して実行される処理のほとんどが,ページ遷移を伴わない非同期通信で実現されている。ここでは,Webブラウザからの処理要求を受けとるところから結果を返却するまでのサーバ側の処理について見ていく。
カタログページからの処理要求は,CatalogServletクラス,つまり自作のサーブレットによって受け取っている。特別なフレームワークや機構などを使っている訳ではなく,単なるJava Servletである。このCatalogServletクラス内では,ビジネスロジックの処理をCatalogFacadeクラスに委譲している。CatalogFacadeクラス内では,JPA(Java Persistence API)を使って,データベースへの操作を実装している。
CatalogServletFacade.jpg
細かく見ていこう。まずCatalogFacadeクラスから。CatalogFacadeクラスは,ServletContextListenerインタフェースを実装している。web.xmlファイル中に 要素を使って登録されているので,サーブレットコンテキストの生成および破棄のタイミングで,contextInitialized()メソッドおよびcontextDestroyed()メソッドが呼び出される。contextInitialized()メソッド内で,サーブレットコンテキスト内に自インスタンスを格納している。CatalogServletクラス内でCatalogFacadeクラスのインスタンス生成の責任を排除する工夫が見られる。サーブレットコンテストに格納されたCatalogFacadeインスタンスは,CatalogServletクラスのinit()メソッド,つまりCatalogServletサーブレットの初期化時に取得され,cfインスタンスフィールドに保持される。
CatalogFacadeクラスでは,Java Persistence APIが使用されている。JPAの@PersistenceUnit注釈により,EntityManagerFactoryインスタンスがemfインスタンスフィールドにインジェクションされる。同じように,@Resource注釈によって,トランザクションを制御するためのUserTransactionインスタンスがutxインスタンスフィールドにインジェクションされる。各ビジネスロジックメソッドの中で,EntityManagerFactoryインスタンスからEntityManagerインスタンスを生成し,データベースへのクエリーの発行とモデルへのマッピングを依頼している。更新系のクエリーについては,当然utxインスタンスフィールドを使用して,トランザクションの境界を決定している。
Webブラウザからの要求を受けとるCatalogServletサーブレットはどのようなコーディングになっているかを次に見ていこう。Webブラウザからの処理要求には,commandパラメータが常に含まれている。commandパラメータは,カタログページに関するWebブラウザからの処理要求の種別を表している。doGet()メソッドでは,commandパラメータの値によって,行うべき処理を分岐している。
CatalogServletクラス内では,各処理の中で以下のような処理を行っている。

  • 渡されたパラメータを元に,CatalogFacadeインスタンスを使用してデータベースアクセスを行い,結果を得る。
  • 得られた結果を元に,Webブラウザに返却する文字列を生成する。
  • 生成された結果の文字列をWebブラウザに送信する。

CatalogFacadeインスタンスは,init()メソッドの中でサーブレットコンテストから取得され,cfインスタンスフィールドに保持された状態になっているため,すぐに使用することが可能である。doGet()メソッド内でcommandパラメータにより分岐されたブロック内で,CatalogFacadeインスタンスに適切な処理を依頼し,結果を得ている。
CatalogServletクラスで重要なのが,各handle〜()メソッドである。handleで始まるメソッドでは,CatalogFacadeインスタンスからの処理結果を元に,Webブラウザに返却する情報を文字列として組み立てている。ほとんどのhandle〜()メソッドでは,XMLの断片として組み立てられているのに対して,handleCategories()メソッドだけはちょっと違う。handleCategories()メソッドでは,format引数の内容が”json”だったときは,JSON形式(JavaScriptのオブジェクト表現)で結果が組み立てられている。format引数の値は,実際にはWebブラウザからパラメータとして渡されている。
このように,カタログページに関しては,Webブラウザ上のJavaScriptコードから発生する処理要求をCatalogServletサーブレットが一手に引き受け,実際のビジネスロジックはCatalogFacadeインスタンスに委譲し,その結果をCatalogServletサーブレット内でXMLあるいはJSONの形式に組み立て,Webブラウザに返却するという構造になっている。
永続化にJPAが使われている点を除けば,基本的には初期のJ2EEの技術のみで作られている。へんちくりんなフレームワークを使って作るよりは,よっぽどこのレベルの方がわかりやすい。もちろん規模が大きくなるに従って素のサーブレットじゃ対応できなくなるのは明白だが,Sunの推奨という位置付けでは,こんくらいが妥当なのは確かだ。

ん?POJOじゃないの?

PetStore 2.0 ea1内で使われているCategoryクラスのコードの冒頭は,以下のような感じ。

package com.sun.javaee.blueprints.petstore.model;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Category implements java.io.Serializable {
  
  private String categoryID;
  private String name;
  private String description;
  private String imageURL;
  
  public Category() { }
  
  @Id
  public String getCategoryID() {
    return categoryID;
  }
・・・

import文に思いっきりJava Persistece APIが登場している。全然POJOじゃないじゃん。当然import文を消すと,@Entityや@Idといったアノテーションが見つからないというコンパイルエラーになる。注釈って単なるマーカー(というか単なる文字列情報)だと思っていたが,これではべったり対象のAPIに依存してしまっている。
うーん,いかがなものか。HIbernateの永続化モデルクラスにすっかり慣れてしまった僕には,かなりの違和感を覚えたコードである。

[追記: 2006/08/04]
EJB3.0 Persistence API(JSR-220)で規定されているアノテーションをO/R-Mappingの領域で標準としましょう,という動きがあって,HibernateもHibernate Annotationでこれを採用しているらしい。つまり,J2EEコンテナ上でEJB3.0やJPAは標準なんだから,エンティティを扱うための抽象的な@Entityや@Idなどのためのimport文が埋まることは問題ない,っていう解釈なのだろう。
完全なPOJOであれば,アノテーションが付いていても,J2EEコンテナ外での動作,つまりEJB3.0やJPAのライブラリがなくても使えるようになっているのが必要とされると思うのだが,そうではないようだ。Javaのアノテーションは,ことJ2EE向けのものについては,POJOに対するこだわりはなく,あくまでEoDのためってことなんだろうな,きっと。

Java PetStore 2.0ea1のインストール

前回の「Java PetStore 2.0ea1のための環境準備」エントリの内容で,NetBeansとGlassFishの準備は整っている。さて,いよいよJava PetStoreのインストールを行う。Java PetStoreは,NetBeansのプロジェクトとして作成されているので,子の環境であれば簡単に動作確認までもっていくことができる。
まずはJava PetStoreの入手から。PetStoreのページからダウンロードページに遷移する。ここにある「javapetstore-2.0-ea1-installer.jar」ファイルをダウンロードする。
このファイルは実行可能jarファイルなので,そのまま「 javapetstore-2.0-ea1-installer.jar」アイコンをダブルクリックし,ライセンス同意ダイアログで[Accept]ボタンを押すことで,javapetstore-2.0-ea1ディレクトリが作成される。このディレクトリを,適当な場所に配置する。
ではさっそくNetBeansに読み込ませてみる。NetBeansを起動し,GlassFishもスタートさせておく。そして,[File]-[Open Project]メニューを選択する。
OpenProject.gif
Open Projectダイアログで,javapetstore-2.0-ea1ディレクトリを選択し,[Open Project Folder]ボタンを押下する。
SelectProject.gif
読み込み処理後,Projectsウィンドウにpetstoreノードが出現する。このノードを展開すると,Web Pagesなどのいくつかのフォルダがあるのがわかるだろう。
PetStoreProject.gif
実行する前に,PetStore用のデータベースを作成する必要がある。データベース作成用のantビルドファイルが同梱されているので,手軽に作成することが可能だ。Filesウィンドウを開き,petstore/setup/setup.xmlファイルの上で右クリックを行い,Run Targetメニューからsetupターゲットを実行する。この際,GlassFishが起動していないと失敗してしまうので注意。
PetStoreDBSetup.gif
正常に作成されれば,GlassFishのJDBCリソースとしてPetstoreDBが登録される。
PetstoreDB.gif
ここまで来れば,PetStoreを実行することができる。Projectsウィンドウのpetstoreノード上で右クリックし,Run Projectメニューを選択する。
PetStoreStarting.gif
ビルドとデプロイが実行され,自動的にWebブラウザが起動して,PetStoreのトップページが表示される。
PetStoreTop.gif
派手な画面を期待していたので「あれ?」という感じだが,「Enter the Store」リンクをクリックすれば,期待したPetStoreのトップページが表示される。
PetStoreTop2.gif
ペットの種類を左から選んでクリックすると,カタログページが表示されて,具体的にペットを選ぶことができる。かなりインタラクティブな操作感。さすがWeb2.0対応である。
あとは,NetBeans上でソースコードを修正などして,[Run Project]を繰り返すことで,PetStoreの仕組みを追っていくことができる。準備完了だ。

Java PetStore 2.0ea1のための環境準備

最近Java PetStoreの2.0ea1を探り始めている。これはSunの今後のアプリケーション構築方針の具体例であり,J2EEアプリケーション開発従事者であれば,抑えておかなければならないコードだろう。完全に時代の最先端に乗り遅れている感が否めないので,その近道としてWeb2.0対応PetStoreをしばらくは見ていく。
ここでは,PetStoreを追っていくための環境の構築について,手順を示してみようと思う。ちなみに,Mac前提だ。
PetStoreはSun純正なので,やっぱりNetBeansで追っていくのが最適だろう。NetBeans5.5のβ版とGlassFishという組み合わせを今回は選択した。NetBeansはここのダウンロードページから,MacOS Xと言語(英語のみだけど)を選んでダウンロードする。GlassFishはここのダウンロードページから「V1 UR1 Build 03 30-June-06」をそれぞれダウンロードする。
NetBeansのインストールは簡単だ。tar ballを展開して,NetBeans.appファイルを得るだけ。NetBeans.appアイコンをダブルクリックすれば,NetBeansが起動する。
次にGlassFishだ。GlassFishのインストール方法は,さっきのダウンロードページに記述されている。実行可能jarファイルなのだが,普通に起動してしまうとheapメモリが不足してしまうため,「java -Xmx256m -jar glassfish-installer-v1_ur1-b03.jar」というようにjavaコマンドを手動で実行する。ライセンス同意ダイアログで[Accetp]ボタンを押すとglassfishディレクトリが生成されるので,適当な場所に移動させる(ここでは/Applications/java/に配置したことにする)。さらにシェルからglassfishディレクトリに移動して「ant -f setup.xml」というようにantを実行すれば,domain1ドメインが生成されてGlassFishが起動可能状態になる。
では,NetBeansからGlassFishを使えるようにしてみよう。NetBeansを起動し,RuntimeタブにあるServersノード上で右クリック。「Add Server…」を選択する。
AddServers.gif
Add Server Instanceダイアログが表示されるので,まずは以下のように「Sun Java System Application Server」「GlassFish」と入力し,[Next]ボタンを押す。
AddServerInstance1.gif
次のパネルでは,以下のように「/Application/java/glassfish」(GlassFishディレクトリ)「Register Local Default Domain」「・・・/domains/domain1」を入力し,[Next]ボタンを押す。
AddServerInstance2.gif
管理者用認証情報を入力する次のパネルでは,以下のように「admin」「adminadmin」(GlassFishの初期値)と入力し,[Finish]ボタンを押す。
AddServerInstance3.gif
すると,GlassFishがNetBeansに登録され,Serversノードに追加される。
AddedGlassFish.gif
では,GlassFishをNetBeansから起動してみる。Serversノードに登録されたGlassFishノードの上で右クリックし,Startメニューを選択する。
StartingGlassFish.gif
Outputウィンドウ内に,「Application server startup complete.」と表示されれば起動完了。同じように,Stopメニューを選択すれば,GlassFishを停止させることができる。
これで,PetStoreのための準備は完了である。

Get Adobe Flash playerPlugin by wpburn.com wordpress themes