- PR -

JSFでアクションマッピング

投稿者投稿内容
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-11-21 15:42
いつもお世話になっております。
JSFについて質問させていただきます。

Strutsではアクションや画面遷移を定義するのに、struts-config内
<action-mappings>の<action>タグにtype属性でアクションを定義します。
その際、同時にparameter属性で引数を設定出来たと思います。

JSFでは同様のことをfaces-config内
<navigation-rule>の<navigation-case>で行うと思いますが、
<from-action>の結果を<from-outcome>でマッピングする事はできても、
引数を渡すことができません(と認識しています)。

同一のアクションクラスを引数によって処理内容及び画面遷移を動的に切り替えたい
といった場合にはどういった方法があるか、ご存知の方がいらっしゃれば、
是非ご教授下さい。

※上記と直接関係はないかもしれませんが、JSP内に記述するJSFタグ(/jsf/html等)の
rendered属性で指定するメソッドに引数を渡す方法はないのでしょうか?
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-11-21 17:37
<h:commandButton>や<h:commandLink>の

action属性が返す値がActionForwardの名前に、
actionListener属性に指定するものがActionに相当します。

action属性もMethodBindingできるので、Backing Beanの
メソッドを指定すれば動的に変更することも可能です。

<f:param>を使いたい場合は、リスナーに渡されるActionEventから
イベントを発生させたコンポーネントを辿ることで取得できます。

#一般的にaction属性のメソッドでAction相当のロジック呼び出しを
#実装することが多いようですが、私は使い分けることをお勧めします。
#actionListener⇒Actionとしたのはその辺りが理由です。
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-11-21 22:22
あしゅさん
ご返信どうもありがとうございます。

@action属性の場合はコンポーネントバインディング
AactionListener属性を使えば、<f:param>でrequestにのせたパラメータを受け取れる
という認識でよろしいでしょうか?
コンポーネントバインディングは極力使わないようにしているので、
Aの方向で考えたいと思います。

ActionとActionForwardを使い分けるのはフォワード先をActionForwardで一元管理して、
BackingBeanやJSPに設定を散在させない為という感じでしょうか?
もし、他に理由があれば後学の為に是非ご教授下さい。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-11-21 23:28
引用:

Dogさんの書き込み (2006-11-21 22:22) より:
ActionとActionForwardを使い分けるのはフォワード先をActionForwardで一元管理して、
BackingBeanやJSPに設定を散在させない為という感じでしょうか?



画面遷移とアクションの実行を分離することが主な理由です。
actionに指定したのではイベントの発生源が伝わらないので、
複数のUICommandから実行できるアクションを実装しにくいですし。

ActionEventから<f:param>を受け取るようにActionListenerを実装すれば、
ViewとActionの結合度を多少なりとも弱められるので、類似機能での再利用や
ページの動的な構成変更にも多少は柔軟に対応できるようになると思いますよ。

また、このルールを徹底すれば、actionをMethodBindingしている箇所は、
動的に遷移先を切り替えている、という意味も持たせられます。
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-11-22 10:44
お世話になっております。

<h:commandButton>,<h:commandLink>について
public void test(ActionEvent actionEvent){
UIParameter param = (UIParameter) actionEvent.getComponent().findComponent("paramId");
//以下アクション
}
のような形でactionListenerからActionEventを受けとる形式でアクションメソッドを実装し、
action属性には<from-outcome>に定義したString値を直接設定するように統一しようと思います。

あしゅさんお付き合い頂き本当にありがとうございます。
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-11-22 13:45
もう解決したようですが、以前、いくつか考えたことがあるので、ご参考までに。
(renderedに対してはどれも今一つですが)。

(1) commandLinkとparamを併用
<h:commandLink value="LINK" action="#{myBean.action}">
<f:param name="param1" value="value1"/>
</h:commandLink>

public String action() {
FacesContext ctx = FacesContext.getCurrentInstance();
Map map = ctx.getExternalContext().getRequestParameterMap();
String param1 = (String) map.get("param1");
return "ok";
}

(2) actionListenerとattributeを併用
<h:commandButton value="button" action="#{myBean.action}" actionListener="#{myBean.processAction}">
<f:attribute name="attr1" value="value1"/>
</h:commandButton>

public void processAction(ActionEvent event) {
UIComponent com = (UIComponent)event.getComponent();
String attr1 = (String)com.getAttributes().get("attr1");
}

(3) faces-config.xmlのmanaged-propertyで指定
<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>ActionBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>prop1</property-name>
<value>value1</value>
</managed-property>
</managed-bean>
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-11-22 14:50
よしだひろゆきさん
いつもお世話になっております。

私が先述したものが
actionListener+parameterとすると、
(1)action+parameter
(2)actionListener+attribute
といったところでしょうか。
アプリケーションの性質に合わせて使い分けたい感じですね。
本来は(3)ですべてのアクションを実装できると「JSF」のメリットを最大限享受できる気がしますが、なかなか・・。

やはりrenderedの指定先をパラメータで動的に切り替えるのは難しいのでしょうか。
例えば・・
会員制のポータルサイトのようなものを作る時、ログインしたユーザの設定によって項目の表示/非表示を切り替えたい。
というような仕様は結構良くあると思うのですが、そういった場合JSFではどのような実装が最適なんでしょうか?
質問ばかりで恐縮ですがご教授頂けたら幸いです。
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-11-29 13:42
引用:

例えば・・
会員制のポータルサイトのようなものを作る時、ログインしたユーザの設定によって項目の表示/非表示を切り替えたい。
というような仕様は結構良くあると思うのですが、そういった場合JSFではどのような実装が最適なんでしょうか?


「renderedのEL式にパラメタを渡したい」というのはようするに、JSPを書く人(Page Author)とサーバ側ロジックを書く人(Application Developer)の両者の判断/ロジックを組み合わせた結果で、あるコンポーネントを表示するか否かを決めたいということですよね。

そういうことであれば、例えばこんな風にできませんか。
ログインしたユーザを表現するmanaged beanを作ってあるでしょうから、そのプロパティとしてそのユーザのstatusを得られるようにしておいて、
<h:outputText ..... rendered="#{user.status == ABCD}"/>
のような感じ。こうすれば、getStatusメソッドのロジックを提供するのはApplication Developerで、その結果を利用して最終判断するのはPage Authorになっています。

スキルアップ/キャリアアップ(JOB@IT)