BT

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

寄稿

Topics

地域を選ぶ

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

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

ブックマーク

もしあなたが今まさにポータルの利用方法について調べているのか、あるいはどれだけ簡単に新しいアプリケーションや既存のJSFアプリケーションをポータル環境に移行できるのか知りたいのだとしたら、この記事は役に立つでしょう。

この数年の間にポータルはエンタープライズの観点から、また、ポートレット2.0(JSR 286(リンク)の仕様による機能拡張によってかなり前進しました。新しくなったポートレット2.0によって異なるアプリケーションそれぞれを一つのページの別々のウィンドウとしてまとめる自由度が増しました。そして勿論、認証機能、洗練されたパーソナライズ機能、そして標準でのAJAX処理の向上も使えるようになりました。

JSR 301(リンク)のポートレット・ブリッジに関する仕様によって、JSFアプリケーションをポートレット1.0、2.0の両方で実行する方法の標準化がなされました。ポートレット・ブリッジはJSFのライフサイクルを適切に処理するためにポータルのAction/Rendererパラダイムを扱います。このチュートリアルの主な目的はどれだけ簡単にJSFポートレットを設定し開発することができるのかを示すことですが、合わせてJBoss Portlet Container 2.0とそれに含まれるいくつかの新機能についても公開していきます。

本編は3回記事の第1回にあたり、JSFポートレットとポートレットの知識からポートレット環境におけるAJAXやSeamの利用方法までをカバーします。

では、はじめましょう。

プロジェクトのセットアップ

開発ツール:

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

サーバ及び見本アプリケーションで使用されるバイナリ:

JBoss Portal’s Portlet Container 2.0
JBoss Portlet Bridge Beta3

現在、JBoss Portlet Bridgeは、JSF/RichFaces/Seamの組み合わせを使える、JSR 301の唯一の実装です。プロジェクト用のMavenの設定はJBoss ASとJBoss Portlet Container 2.0をまとめてダウンロードするようにセットアップされています。もし別々にダウンロードしたい場合には、こちら(リンク)で見つけることができます。標準のままでよければ、Mavenが次のステップのために適切なファイルをダウンロードする数分間、待っててください。

注意 - このポートレットはJBoss Portalの最新版である2.6.5.SP1上でも稼働します。筆者はこの記事内でJBoss Portlet Container 2.0を利用していますが、ブリッジはどちらでも機能します。他のバージョンのJBoss Portal上での稼働方法についてはこちら(リンク)で確認できます。

初心者向け(またはテンプレート)プロジェクトを利用しててっとり早く始めるには下記にあるMavenのarchetype(リンク)を利用すると便利です。一度このコマンドを実行すれば、開発とこの紹介記事に必要な全てのものがそろいます。

まずターミナルを開いて以下のコマンドを実行します:

mvn archetype:generate -DarchetypeGroupId=org.jboss.portletbridge.archetypes
 -DarchetypeArtifactId=1.2-basic
 -DarchetypeVersion=1.0.0.B3 -DgroupId=org.whatever.project -DartifactId=myprojectname
 -DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B3

続けて新しいプロジェクトを作成したディレクトリに移動します。上記の例をそのまま利用した場合には、"myprojectname"がディレクトリになります。ざっと眺めて、作成されたファイルに目を通して見て下さい。Maven標準のフォルダ構造とこのチュートリアル用のソース・コードがあると思います。これで、お気に入りのIDEを立ち上げてこのMavenプロジェクトをインポートすることができます。

ポートレット・ブリッジの設定方法

ここから先はサーブレットの世界でJSFアプリケーションを開発するのと大して変わりません。唯一の違いは、シングル・サイン・オンやportletContext、ネームスペースを考慮した変数へのアクセスそして'Help'や'Edit'などのポートレットのウィンドウ・モードといったものの取り扱いになります。ポートレットの世界についてあまり詳しく書く気はありませんが、基本的な開発に必要な情報は公開していきます。ポートレットに関するより詳細な情報が必要でしたらJSR 168(リンク)やJSR 286(リンク)の仕様を読んでみてください。

JBoss Portlet Bridgeのカッコイイところは、それ自体はポートレットではないということです。JBoss Portlet Bridge自体はポートレットとJSFの世界の仲介をしているに過ぎません。WEB-INFディレクトリには3,4つの余分なxmlファイルとブリッジ用のjarがあると思います、しかし、それ以外はサーブレット版のアプリケーションと何も変わりありません。唯一の違いが下記の設定ファイルです。:

portlet.xml

<portlet>
       ...v       <portlet-class>
          javax.portlet.faces.GenericFacesPortlet
       </portlet-class>
       <init-param>
          <name>javax.portlet.faces.defaultViewId.view</name>
          <value>/home.xhtml</value>
       </init-param>
       <init-param>
          <name>javax.portlet.faces.defaultViewId.edit</name>
          <value>/jsf/edit.xhtml</value>
       </init-param>
       <init-param>
          <name>javax.portlet.faces.defaultViewId.help</name>
          <value>/jsf/help.xhtml</value>
       </init-param>
       ...
 </portlet>

web.xml

<context-param>
       <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
       <param-value>
          org.jboss.portletbridge.application.FaceletPortletViewHandler
       </param-value>
    </context-param>
    <context-param>
         <param-name>javax.portlet.faces.renderPolicy</param-name>
         <param-value>
             ALWAYS_DELEGATE
         </param-value>
  </context-param>

faces-config.xml

 <application>
      <view-handler>
          org.jboss.portletbridge.application.PortletViewHandler
      </view-handler>
      <state-manager>org.jboss.portletbridge.application.PortletStateManager</state-manager>
 </application>

先にセット・アップしたMavenのarchetypeには上に挙げた設定が既に反映されています。ここまできたらプロジェクトをコンパイルしてJBoss Portalにデプロイしましょう。

デモ・アプリケーションの実行

プロジェクトをコンパイルして以下の2ステップでデプロイします:

 

ステップ 1: mvn install cargo:start -Premote-portal -Dpc20

コマンドを実行するとサーバとポータルをまとめてダウンロードするのに数分間かかるのでしばらく待って下記の画面が表示されてから次のステップに進んで下さい。:

*注意 - サーバが起動する前にPortletExceptionが出力されると思いますが何の問題もありません。Portlet Container 2.0のデモに含まれるFailDuringInitPortlet(ポートレット初期化の失敗)の一部です。 

次に別のターミナル・ウィンドウを開いて、JSFポートレット・プロジェクトのルートへ移動して下記コマンドを実行します:

ステップ 2: mvn cargo:deploy -Premote-portal -Dpc20

コマンド・ライン・パラメータでJBoss+Portalセットのロケーションとどのバージョンのポータルで実行するのかをcargo(プラグイン)に示しています。この見本アプリケーションはJSR 168に準拠した最新版のJBoss Portal 2.6.5.SP1上でも稼働します。より詳細な情報とMavenのコマンドについてはJBoss Portlet Bridgeのドキュメントにあるこの項目(リンク)を確認してください。デプロイされたJSFポートレットを見るには:http://localhost:8080/simple-portal/demo/jsr-301.jsp (リンク)を見て下さい。:

JSFポートレットの開発

では、ポートレットとJSFの開発を結び付けてる部分について見ていきましょう。

ポートレットを通常のWebアプリケーションとして見てみる

アプリケーションをサーブレット・サイドのWebアプリケーションとして見てみるとポートレット・ブリッジは透過的です。ポートレット開発者にとっては、開発中のアプリケーションがポートレット環境で実行しているせいでおかしな動き*をしている訳ではないということを確認するために時々チェックをするのはいいことだと思います。このデモ・アプリケーションやブリッジを使ってデプロイした他のあらゆるアプリケーションを確認するにはhttp://localhost:8080/JSFRIPortlet/home.jsf (リンク)を見て下さい。

ネームスペース

ブリッジはポータル環境におけるJSFのネームスペースの組み合わせを処理します。JSF/xhtmlのマークアップ内の要素にidを使う必要がある場合、通常はレンダリングされたマークアップ内に'form1:myBtn'のような記述があるでしょう。しかしブリッジがネームスペースを処理するとこれが下記のような記述になります:
jbpns_2fdefault_2fNews_2fStories_2fStoryTemplateWindow12snpbj:_viewRoot:form1:myBtn

この表現を抑えるために、Faceletのページ内のjavascriptのコードで頭にネームスペースを付けるために下記のような表現を使うことができます:
document.getElementById('#{facesContext.externalContext.response.namespace}the_rest_of_JSF_ID');

一つ気を付けて欲しいのはこの方法はportletResponseを利用するので、このページをサーブレット・アプリケーションとして表示しようとすると例外が発生するということです。これを避けるには、(JSFの)Backing Bean内でレスポンスの種類をチェックしてUIには適宜"安全な"ネームスペースを付与することです。

preserveActionParams

web.xml内でpreserveActionParamsがTRUEにセットされていると、ブリッジはあらゆるリクエスト・パラメータをポートレットへのアクション・リクエストに関連付けて保持しておく必要があります。この場合、リクエスト・パラメータは"bridge request scope(ブリッジ・リクエスト・スコープ)"に保持されます。このパラメータ(preserveActionParams)が設定されていないかあるいはFALSEに設定されている場合には、アクションへのリクエスト・パラメータはポートレットのリクエスト・スコープの範囲内にしか保持されません。

<init-param>
     <param-name>javax.portlet.faces.preserveActionParams</param-name>
     <param-value>true</param-value>
 <init-param>

Faceletのページ内で#{request.yourParam}のように記述すればこの設定を利用できます。

ブリッジ・リクエスト・スコープから特定のアトリビュートを除外する

もしアプリケーションでリクエストの都度リクエスト・アトリビュートを使っていてある特定のアトリビュートはブリッジ・リクエスト・スコープで管理されたくないと思うのなら、faces-config.xmlに以下の設定をすべきです。以下の例ではfoo.barというネームスペースで始まる全てのアトリビュートもしくはfoo.baz(ワイルドカード)で始まるネームスペースの全てのアトリビュートはブリッジ・リクエスト・スコープから除外され、そのアプリケーションに対するリクエスト内でのみ利用されます。:

  <application>
           <application-extension>
               <bridge:excluded-attributes>
                   <bridge:excluded-attribute>foo.bar</bridge:excluded-attribute>
                   <bridge:excluded-attribute>foo.baz.*</bridge:excluded-attribute>
               </bridge:excluded-attributes>
           </application-extension>
   </application>

(ブリッジ)リクエストに含めたくないオブジェクトのクラスにjavax.portlet.faces.annotation.ExcludeFromManagedRequestScope アノテーションを書くことによって同じ目的を果たすこともできます。

結論

ここまで見てきたように、JSR 301の仕様によって既存のJSFアプリケーションを簡単にポートレットに仕立てることが出来るようになるだけでなく、あなた(開発者)がJSFとポートレットの差を処理する方法を提供するのです。そういうわけで、仕様についてはまだレビューと改訂が繰り返されています。この記事を書いているときにはEarly Draft Review 3が最新のパブリック・バージョンでしたが、JSR 301専門部会内では既にこのバージョンに対して多くの改良がなされています。ブリッジに対する大きな改良点の一つはポートレット・モードに対するナビゲーションと状態で、これらはJBoss Portlet Bridgeの次期バージョン(ベータ4)で取り込まれる予定です。

プロジェクトやブリッジがサポートするその他のバージョンについてもっと詳しく知りたい方、コミュニティに参加したい方はぜひプロジェクトのページ(リンク)及びブログ(リンク)を訪れてみてください。

 

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

この記事に星をつける

おすすめ度
スタイル

BT