JSF 2.0 : ブックマーク可能な URL (GET リクエスト) のサポートと動的パラメータ設定
今回紹介する機能は恐らく多くの JSF の開発者が求めてきた機能の一つかと想定しますが、JSF 1.2 までは画面遷移を行う際 h:commandLink, h:commandButton を使用して POST による遷移しかできませんでした。しかし JSF 2.0 からは GET による画面遷移も可能になりました。GET による画面遷移を行うためには、h:link, h:button を利用します。また、これらのタグは JSF のナビゲーションルールに従い画面遷移ができるようになっています。
例えば、JSF 1.2 では下記のように直接遷移先の URL をコード中に埋め込んでいました。
<h:link value="next.xhtml" value="リンク"/>
しかし、JSF 2.0 からは h:link, h:button の2つのコンポーネントに対して outcome の属性を指定し遷移先の view ID を指定しナビゲーションルールを設定できるようになりました。例えば、下記のように記載します。
<h:link outcome="viewEntry" value="リンク"/>
この際、上記の「リンク」をクリックすると下記のコンテンツが表示されます。
http://localhost:8080/JSF-Bookmark/faces/viewEntry.xhtml
これは faces-config.xml にナビゲーションルールを記載していないため、デフォルトの遷移先である vewEntry.xhtml に遷移しています。また、EL 式で CDI/Managed Bean のメソッドを指定する事で動的に遷移先を変更する事も可能です。下記の例では、SomeBean#entry() メソッドが呼び出されるため、entry() メソッドでは遷移先の view ID を文字列で返す必要があります。ちなみに outcome の属性はページ内にリンクを記載するため、必ず画面がレンダリングされる前に評価されます。
<h:link outcome="#{someBean.entry}" value="リンク"/>
URL パラメータの指定
次に、HTTP リクエストに対してパラメータを指定する方法を紹介します。GET メソッドにパラメータを付加するためには下記の何れかの方法で行います。
- outcome 属性に直接記載(画面遷移時に使用)
- View Parameters の使用(アクセス時に使用)
- f:param タグの使用(画面遷移時に使用)
まず、画面遷移時に利用可能な outcome 属性に直接記載する方法ですが、下記のように記載します。複数のパラメータを指定する際は、&amp; を記載します。
<h:link outcome="viewEntry?query=10&result=5" value="リンク"/>
また、下記のように outcome 属性中に EL 式を記載する事も可能です。
<h:link outcome="viewEntry?query=#{someBean.query}" value="リンク"/>
次にアクセス時に利用可能な View Parameter を紹介します。JSF 2.0 では View のパラメータを扱うために特別な UIInput コンポーネント UIViewParameter を追加しました。UIViewParameter は UIInput を継承しているため、他の通常のコンポーネントと同様にコンバータやバリデータを扱う事ができます。また EL 式を記載する事ができ動的な値を扱う事もできます。UIViewParameter を使うためには f:metadata 中で <f:viewParam/> を追加して使用してください。f:viewParam の使用例を下記に示します。
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <f:metadata> <f:viewParam id="data" name="data" value="#{someBean.data}" /> </f:metadata> <h:head> <title>Sample</title> </h:head> <h:body> <h:link outcome="viewEntry" value="リンク"/> #{' '} <br/> <h:outputLabel value="#{someBean.data}"/> </h:body> </html>
f:viewParam で指定した Managed Bean を下記に示します。
package managed; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; @ManagedBean @RequestScoped public class SomeBean { private String data; public String getData() { return data; } public void setData(String data) { this.data = data; } }
このページにアクセスする際は、URL の引数に ?data=foobar を付加してアクセスします。
http://localhost:8080/pathToWebapp/view.xhtml?data=foobar
すると、myBean の setData() が呼び出され data に対して foobar が セットされます。そして画面をレンダリングする際、myBean#getData() が呼び出され、data にセットした foobar という文字列が表示されるようになります。URL の引数指定 (?data=foobar) を必須にしたい場合は、required=”true” を付加します。これを指定すると引数が指定されていない場合は例外が出力されます。
<f:metadata> <f:viewParam id="data" name="data" value="#{someBean.data}" required="true"/> </f:metadata>
さらに、前述したようにバリデーションを記載する事も可能なため、下記のように View Parameter に指定する文字列の長さも検証する事が可能になります。
<f:metadata> <f:viewParam id="fname" name="data" value="#{someBean.data}" required="true"> <f:validateLength minimum="5" /> </f:viewParam> </f:metadata>
※ デフォルトで表示される翻訳されたエラーメッセージはひどいのですが、エラーメッセージは独自の内容に変更する事が可能です。
最後に画面遷移をする際に利用する f:param タグの使用方法を紹介します。
f:param は他の画面に遷移する際 URL に付加するパラメータを組み込んで画面遷移ができるようになります。例えば、下記のコードを記載した場合を想定してください。
<h:link outcome="viewEntry" value="リンク"> <f:param name="getParam" value="getValue"/> </h:link>
実行して「リンク」を押下すると、下記の URL に遷移し URL にパラメータが指定できている事がわかります。
http://localhost:8080/JSF-Bookmark/faces/viewEntry.xhtml?getParam=getValue
また、ナビゲーションルールを faces-config.xml の設定ファイルに記載したい場合は下記のように設定ファイルを記載する事でナビゲーションルールを記載する事もできます。
<navigation-rule> <from-view-id>/index.xhtml</from-view-id> <navigation-case> <from-outcome>viewEntry</from-outcome> <to-view-id>/page2.xhtml</to-view-id> <redirect> <view-param> <name>getParam</name> <value>#{someBean.value}</value> </view-param> </redirect> </navigation-case> </navigation-rule>
上記のように、f:param は別の画面に遷移する際にパラメータを指定できる事がわかります。
最後に、JSF 2.0 は JAX-RS で提供する全メソッドには対応しておりませんが、GET アクセスで Bookmark 可能なサイトを構築するために最低限必要な機能を兼ね備えています。またここに記載した内容を使って、GET/POST のリクエスト間でデータ交換等もできるようになります、JSF 1.2 の頃に比べるとかなり簡単になったリクエスト処理を是非お試しください。
Entry filed under: 未分類.
1.
さもさも | 2011年3月26日 6:02 午前
画面(managed-bean)間の値受け渡しに悩んでいました。
助かりました!
最初、jspで組んでて、やがタグライブラリにありませんって怒られて悩みました。
思い切って、faceletsに移行しました。jspで出来ないことが色々出来るようになりました!
2.
さもさも | 2011年3月26日 6:03 午前
↑あぁ、タグを書いたら省かれた。。。
f:metadataやf:viewParam
でした。