思ってることってこんなもんだよ
カタログページに関するサーバ側の風景

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の推奨という位置付けでは,こんくらいが妥当なのは確かだ。