BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル JSF, Ajax, そしてSeamによるポートレット開発(パート3/3)

JSF, Ajax, そしてSeamによるポートレット開発(パート3/3)

このシリーズのパート1(参考記事)とパート2(参考記事)ではポートレット・ブリッジがどういうものなのか、そのインストール方法及び基本的なJSFとRichFaces(Ajax)ベースのポートレットにおける使い方、そして現在はJBoss Portlet Bridge上での稼働がサポートされているポータル・サーバの主な違いについてを説明しました。最終回となる今回の記事ではSeamポートレットの開発と合わせてJBoss Portlet Bridge(リンク)の最新版ベータ4でカバーされる全ての機能とその利点に焦点を当てています。しかし、ポートレットが初めての読者は前出の2つの記事に遡って読むとよいでしょう。

では早速Seamポートレットの開発の話に入りましょう。

Seam Portletのセットアップ

開発ツール:

これ以降のガイドを見ていくために最新のMavenをダウンロードして下さい。(私は2.0.9を使用しています)
Maven 2.0.9+(リンク)をインストールします
Mavenの各種バイナリにパスを通します(リンク)

プロジェクトの作成:

それぞれのMavenのarchetype(リンク)によって各ブリッジに違いが生まれます。Seamポートレットのプロジェクトをセットアップするためにコマンド・ラインから以下のコマンドを実行してください。

mvn archetype:generate
 -DarchetypeGroupId=org.jboss.portletbridge.archetypes
 -DarchetypeArtifactId=seam-basic -DarchetypeVersion=1.0.0.B4
 -DgroupId=org.my.project -DartifactId=seamproject
 -DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B4 

このarchetypeはモジュール式です。というのは、保守を簡単にし、コード、リソースそして設定をきれいに分離するために生成されたプロジェクトは複数のサブプロジェクトに分割されているということです。'web'ディレクトリにはマークアップ、画像そしてWEB-INFにあるxml設定ファイルが含まれています。'ejb'には全てのSeam EJB3のソース・コードと永続化及びEJBのデプロイに関連する全てのxml設定ファイルが含まれています。最後に、'ear'ディレクトリは主にプロジェクト全体をつなぎ合わせてearをビルドするために使われます。

上記のarchetypeを利用した場合'seamproject'ディレクトリがあるはずです。そのディレクトリに移動して次のコマンドを実行して下さい。:
mvn install
このコマンドによってローカルのMavenリポジトリに存在してない全てのartifactがダウンロードされ、コンパイルとearファイルのビルドが実行されます。

ポートレットの実行とデプロイ:

ここまででデプロイ可能なearファイルが作成されたので、次のコマンドによってこの新しいポートレットをJBoss Application Serverに含まれる最新のJBoss Portalにデプロイして起動します。既にローカルにインストールされているか、地震でダウンロードまたは作成したバンドルがある場合、JBoss Portlet Bridgeのドキュメント(リンク)に独自設定の方法が書いてあるでしょう。

{seamプロジェクト}/earディレクトリに移動して次のコマンドを実行して下さい。

mvn cargo:start -Premote-portal-Dportal-2.7.0.B1
※訳注1*

このコマンドの実行によってSourceForge.netにある最新のJBoss Application Server + JBoss Portalをダウンロードするのに数分(接続環境次第です)かかります。上図に似通ったログが表示されたら次のステップに進んでください。*注意 - ログにWSRPというメッセージが繰り返し表示されるかもしれませんが、これもまた次のステップへ進むための合図になります。

続いてSeamプロジェクトのearをデプロイするため、新しいターミナルを起動し、同じく{seamプロジェクト}/earディレクトリから以下のコマンドを実行して下さい。

mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1
※訳注2*

サーバーログ上にearのデプロイが完了したメッセージが表示されたら、http://localhost:8080/portal/portal/default/seamprojectにアクセスしてみ下さい。下記のページが表示されるはずです。

これで、開発に使うSeamポートレットが完成しました。勿論、どのようにアプリケーションを記述するかは開発者次第です。しかし、この方法によって些細な環境設定の問題から解放され簡単に始めることができるのです。

設定

JSFポートレットを完全なSeamアプリケーションへ変換するにはいくつかの設定さえすれば済みます。前出の(パート1(参考記事)とパート2(参考記事))記事にあった設定に下記の設定を追加します。全体を確認するには、JBoss Portlet Bridgeのドキュメントにあるconfiguration(設定)の欄(リンク)を見て下さい。

web.xml
------------------

下記の設定は一般的なSeamアプリケーションに共通の設定でポートレット環境に固有のものではありません。

      <listener>
      <listener-class>
              org.jboss.seam.servlet.SeamListener
          </listener-class>
    </listener>
    <servlet>
      <servlet-name>Seam Resource Servlet</servlet-name>
      <servlet-class>
              org.jboss.seam.servlet.SeamResourceServlet
          </servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>Seam Resource Servlet</servlet-name>
      <url-pattern>/seam/resource/*</url-pattern>
    </servlet-mapping>
    <filter>
      <filter-name>Seam Filter</filter-name>
      <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>Seam Filter</filter-name>
      <servlet-name>Faces Servlet</servlet-name>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>INCLUDE</dspatcher>
   </filter-mapping>

ExceptionHandlerというコンテキスト・パラメータによってブリッジはSeam由来の例外を組み込みの例外ハンドラで適切に処理することができます。必要であればこの部分に独自の実装を利用することができます。

<context-param>
    <param-name>org.jboss.portletbridge.ExceptionHandler</param-name>
    <param-value>
       org.jboss.portletbridge.SeamExceptionHandlerImpl
    </param-value>
 </context-param>

Bridgelet(ブリッジレット)というのはポートレット・ブリッジ*の拡張機能の名称です。ポートレット・ブリッジのコミュニティはJBoss Portal、SeamそしてRichfacesに対して機能強化や機能統合をする拡張機能を作成中です。例えばPortalIdentity(SSO:シングル・サイン・オン)というseamコンポーネントによって、クラスパス上にjarファイルを置くだけでSeamとPortalの間でSSOが利用できるようになります。(下にあるように)Mavenのpomへdependencyとして設定することでもこの拡張機能を利用することができます。

もしあなたにBridgeletのアイディアがあるか、JBoss Portlet Bridgeの開発の一部でも手伝いたいと思ったら、ぜひ私達のフォーラム(リンク)に参加してJiraタスク(リンク)を提案することを勧めます。

JBoss PortalとSeamアプリケーション間のシングル・サイン・オン

Seam Booking Demo(Seamによる予約デモ・アプリ)は開発者が参考にしたり、テストしたりするのに使うことのできるポートレットです。以降のため、そしてSSO Bridgeletを試すためにhttp://anonsvn.jboss.org/repos/portletbridge/tags/1.0.0.B4/examples/seam/booking/よりデモのソース・コードをチェック・アウトして、この記事に書いてあると全く同じコマンド(あるいは下記に示した短縮版のコマンド)を実行してアプリケーションをデプロイ、起動してください。

短縮版は以下のようになります。
{SeamBooking}へ移動して次のコマンドを実行します。
mvn install

{SeamBooking}/earディレクトリへ移動して次のコマンドを実行します。
mvn cargo:start -Premote-portal-Dportal-2.7.0.B1

Seamプロジェクトのearファイルをデプロイするため、新しいターミナル画面を開いて、同じく{SeamBooking}/earディレクトリから次のコマンドを実行します。
mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

デモの起動が完了したら、http://localhost:8080/portal/portal/default/SeamBookingを開き、"Register New User"をクリックして新しいアカウントを作成し、作成したユーザ名とパスワードでログインしてみてください。

ログインすると、ホテル検索画面とロール・ベースのアプリケーションのパーツが表示されます。しかし、画面の右上角を見ると、SeamアプリケーションにログインしてもJBoss Portalのuser/adminアカウントには何も起きていないことが分かると思います。

そこで私達はSSOブリッジレットを作成しました。これによってSeamのアイデンティティ・モジュールを通してJBoss Portalのユーザを認証することが出来るようになります。では、早速試してみましょう。
サーバは起動させたままにしておいて、デプロイを行ったのと同じターミナル画面で一つ上のディレクトリである{SeamBooking}/ ルート・ディレクトリに戻って次のコマンドを実行します。
mvn install -Psso

次に{SeamBooking}/earディレクトリに戻って下記のコマンドを実行します。
mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

これらのコマンドによってアプリケーションにSSOのjarを組み込み、再度earをデプロイすることが出来ました。

では、http://localhost:8080/portal/portal/default/SeamBookingのポートレットに戻って、今回はSeamアプリケーションではなくてポータルにログインしてみましょう。最上部右隅にあるポータルのログインをクリックしてユーザ名とパスワードの両方に'admin'を入力します。

もしこれが実運用するアプリケーションだとしたら、ほんの少しUIを変更してSeamアプリケーションのログイン・フォームを隠し、SSOを導入したのでその他サイト上のロール・ベースの部分を修正するところです。しかし、先にも述べたようにこれは、Seam Booking Demoを少しだけ修正した入門用のアプリケーションです。

JBoss Portalにログインすると、以下の画面が表示されるはずです。

これ以降、SeamアプリケーションとPortalの間で認証、認可の情報を扱うような開発がより簡単に行えるようになります。もしあなたのSeamポートレットがMavenベースのものだとしたら、必要なのはpom.xmlに下記の記述を加えることだけです。

  <dependency>
      <groupId>org.jboss.portletbridge.extensions.seam</groupId>
      <artifactId>PortalIdentity</artifactId>
      <version>1.0.0.B4</version>
 </dependency>

あるいは単にアプリケーションのWEB-INF/libディレクトリにPoralIdentity.jarを置くだけです。他の設定は一切必要ありません。

JBoss Portlet Bridge ベータ4概説

これが三部作の最後の記事になりますので、この最後の節では9月11日にリリースされたベータ4の新機能について述べます。

PortletModeの移行に対応

PortletModeはアプリケーション内の別々のレンダー・パスを表します。view, editそしてhelpという三つの標準的なモードがあります。JBoss Portlet BridgeのExternalContext.encodeActionURLはjavax.portlet.faces.PortletModeというクエリ・ストリング・パラメータを認識してその値をその時のポートレットのactionURLやレスポンスに対するポートレットのモードとして利用します。一旦処理するとクエリ・ストリングからこのパラメータを除去します。つまり、以下のナビゲーション・ルールはeditモードで\edit.jspxというviewIdをレンダリングすることを意味します。

 <navigation-rule>
     <from-view-id>/register.jspx</from-view-id>
     <navigation-case>
     <from-outcome>edit</from-outcome>
       <to-view-id>/edit.jspx?javax.portlet.faces.PortletMode=edit</to-view-id>
     </navigation-case>
 </navigation-rule>

同一モードの直前のviewIdへのナビゲーション

モードの移行は各モードのデフォルト・ビューから始まり、一切の状態を保持していません。あるモードから別のモードへ移行した後に再び元のモードに戻る場合(例えば、view -> edit -> view)、最後に元のモードで表示されたビュー(とその状態)に戻るというのが一般的なポートレットのパターンです。ブリッジはひとつ前のモードに戻る際に適切なビューと状態を再現できるように必要な情報を明示的にエンコードします。ブリッジが管理するセッション・アトリビュートはあるモードから一つ前のモードの適切なビューと状態に遷移させるために開発者が利用することを意図されています。このような場合、開発者は"ビューXから最後にYモードで表示されたビューに戻る"と言ったように動的に遷移先を表現する必要があります。これに対しては以下のようなEL式で表現するのが最も簡単な方法です。

 <navigation-rule>
     <from-view-id>/edit.jspx*</from-view-id>
     <navigation-case>
       <from-outcome>view</from-outcome>
       <to-view-id>#{sessionScope['javax.portlet.faces.viewIdHistory.view']}</to-view-id>
      </navigation-case>
  </navigation-rule>

ポートレット開発者に向けて

ブリッジの実装によりますが、このようなセッション・アトリビュートやクエリ・ストリング・パラメータが付加されたviewIdを利用する際にはルールを指定する際にワイルドカードを使用する必要があるでしょう。例えば、上記の<to-view-id>の表記は/viewId?javax.portlet.faces.PortletMode=view&.... のようなviewIdを返します。ワイルドカードがないと、このビューに続く遷移があった場合に、完全に一致するものが見つからないためにナビゲーション・ルールが解決されないことになるでしょう。

同様に、上のedit.jspx<to-view-id>と記述してあるもそれを宛先とするナビゲーション・ルールがクエリ・ストリング(<to-view-id>/edit.jspx?javax.portlet.faces.PortletMode=edit)を含んでいるのでワイルドカードを指定しています。開発者は一番緩いブリッジ実装でも正確に実行されるようにこのようなワイルドカードを使用することが望まれます。

ポートレットでAjaxエラーをハンドリングする

デフォルトでは、Ajaxリクエストに対するエラーは標準のサーブレット・ページに送信されます。ポートレット内部でエラーをハンドリングするには下記のjavascriptを記述してください。

<script type="text/javascript">
     A4J.AJAX.onError = function(req,status,message){
          window.alert("Custom onError handler "+message); 
     }

     A4J.AJAX.onExpired = function(loc,expiredMsg){
     if(window.confirm("Custom onExpired handler "+expiredMsg+" for a location: "+loc)){
          return loc;
     } else {
          return false;
     }
  }
 </script>

まとめ

前述のように、ポートレット・ブリッジのコミュニティは既にパッチを提供し始め、ベータ状態にありながらその他サポートも行っています。プロジェクトの中心はJSR-301仕様ですが、Seam、Richfaces、そしてBridgeletやその他の拡張機能と一緒にPortalを利用してシステムを構築することは無限の可能性を秘めています。何人もの開発者がプロジェクトに寄与しています。私達は既にパッチや拡張機能を提供していただいた方、フォーラムでの質問に対する回答を助けていただいた方、その全てに感謝の気持ちを伝えたいと思います。

最後に、これはコミュニティ・ベースのプロジェクトです。多くの開発者が参加して手助けとフィードバックをしてくれるほど、優れたコードと機能拡張を素早くリリース出来るようになります。GAリリースは'09年の早い時期に行われる予定です。

フォーラム(リンク)を通してのフィードバックはとても有効で歓迎します。JBoss Portlet Bridgeプロジェクトに関するより詳細な情報はプロジェクトのWebサイト(リンク)とドキュメント(リンク)を確認して下さい。

※訳注1*
このままでは失敗しました。cargoの前に'install', -Dの前に半角スペースが必要でした。
mvn install cargo:start -Premote-portal -Dportal-2.7.0.B1

※訳注2*
同じく、-Pの前に半角スペースが必要でした。
mvn cargo:deploy -Premote-portal -Dportal-2.7.0.B1

 

原文はこちらです:http://www.infoq.com/articles/jsf-ajax-seam-portlets-pt-3
(このArticleは2008年9月16日に原文が掲載されました)

この記事に星をつける

おすすめ度
スタイル

BT