- PR -

JSFでエラーメッセージ表示時に前回のform値が残っている

1
投稿者投稿内容
KG
会議室デビュー日: 2006/01/05
投稿数: 10
投稿日時: 2006-01-05 13:12
JSFでシステム開発を行っています。
Formの入力値チェックを行い、エラーがあった場合
FacesContext.getCurrentInstance().addMessage()メソッドを使用してメッセージを追加しています。

このとき、エラーがあった場合に他画面に遷移し、再度同じ画面を表示させると
表示時にバッキングビーンで初期値を設定しているのにもかかわらず
前回のForm値がのこったままとなります。
例)
@メニュー画面

A入力画面

B入力画面で入力エラー

Cメニューに戻る

D入力画面←ここで、画面にはBの値が残っている

入力画面の値を保持するマネージドビーンのスコープをrequestにしても、前回の値が残ったままとなります。
画面遷移はすべてforwordで行っています。
(redirectでも試してみましたが、やはり残ってしまいました)
HTMLのヘッダでキャッシュを使用しない設定はしています。
(下記の設定をしています)
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache,no-store">

どなたか、このような現象の解決策をご存知ないでしょうか?
非常に困っております。どうかよろしくお願いいたします。


[ メッセージ編集済み 編集者: KG 編集日時 2006-01-05 13:12 ]
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-01-05 15:45
JSFは次のように動作します.
Apply Request Valuesフェーズでサーブレットパラメタから入力値をdecodeして
コンポーネントのSubmittedValueとします.
Process ValidationsフェーズでSubmittedValueをコンバートし,バリデートして
LocalValueとします.このときSubmittedValueはnullに戻ります.
Update Model ValuesフェーズでLocalValueをバッキングビーンにセットし,
このときにLocalValueはnullに戻ります.

以上の動作の途中でエラーがあると,Render Responseフェーズへ進みます.
Render Responseフェーズでは,SubmittedValueが残っていればそれを使います.
次にLocalValueが残っていればそれを使います.
SubmittedValueもLocalValueもnullの時に,バッキングビーンを参照します.
だから,エラーがあると入力値が再表示されます.

エラーが無くてInvoke Applicationフェーズが実行されて
Navigation Handlerがviewを変更すると新しいコンポーネントツリーが生成されます.
このとき,同じviewであっても新しいコンポーネントツリーを生成します.
仕様書の7.4.2 Default NavigationHandler Implementationに
A rule match always causes a new view to be created, losing the state of the old
view.
と既定されていますので.

ということで,KGさんは通常の画面遷移機能を使わないで何か別の方法で入力画面に
戻っているのではないかと思いますが,いかがですか?
KG
会議室デビュー日: 2006/01/05
投稿数: 10
投稿日時: 2006-01-05 17:20
よしだひろゆきさん

早速のご返答ありがとうございます。
確かに、Invoke Applicationフェーズが実行されないと前回の値が残りました。
<h:commandButton/>にimmediate="true"を設定して実行してみたところ、
エラーがなくても同様の現象が起こりました。

画面遷移については、
メニューに戻る場合、以下の方法を試しましたがいずれも同じ現象が起こっています。

@outputLinkでメニューページのURLを直接指定

AcommandButtonでactionに直接メニュー画面に戻る<from-outcome>を記述
[jsp]
<h:commandButton type="submit" action="back" value="戻る" immediate="true"/>

[faces-config.xml]
<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>back</from-outcome>
<to-view-id>(メニューのURL)</to-view-id>
</navigation-case>
</navigation-rule>

Bバッキングビーンでメニュー画面に戻る<from-outcome>を戻す
[jsp]
<h:commandButton type="submit" action="#{test.doBack}" value="戻る" immediate="true"/>
(doBackの戻り値が"back"、faces-configはAと同じ)

現在の画面の入力内容を破棄して他画面に遷移したい場合、以上の方法では何か間違っているのでしょうか?
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-01-06 13:40
引用:
確かに、Invoke Applicationフェーズが実行されないと前回の値が残りました。
<h:commandButton/>にimmediate="true"を設定して実行してみたところ、
エラーがなくても同様の現象が起こりました。


少々誤解されているようです.immediate="true"はApply Request Valuesフェーズにて
アクションを実行するという意味なので,アクションは実行されます.
デフォルトでは,アクションを実行するとrenderResponseフラグが立つので
その結果,Process ValidationsとModel Value Updateをスキップするので,
SubmittedValueがコンポーネント内に残ります.

問題は相変わらず「なぜアクションを実行しているのにコンポーネントツリーが再生成されないのか」ですね.

引用:
画面遷移については、
メニューに戻る場合、以下の方法を試しましたがいずれも同じ現象が起こっています。


問題はメニュー画面に行く方法ではなくて,入力画面に戻る方法です.
入力画面のコンポーネントツリーがNavigationHandlerによって再生成されないのが原因だと思います.
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-01-06 14:12
分かりました.メニュー画面はJSFではなくて,通常のHTMLorJSPですね.
だから入力画面への遷移でコンポーネントツリーが再構築されないのです.

とりあえず,state saving methodをclientにすれば解決します.

serverを使う場合は,メニュー画面をJSFにするか,JSPにしてその中でsession情報に
登録されているコンポーネントツリー情報をnullにすれば良いかと思います.
KG
会議室デビュー日: 2006/01/05
投稿数: 10
投稿日時: 2006-01-08 12:20
よしだひろゆきさん
回答ありがとうございます。

メニュー画面もJSFなのですが・・・なぜなのでしょうか・・・

とりあえず解決策としては、入力画面初期表示処理時に
コンポーネントツリー内のSubmittedValue、LocalValueをクリアすることで解決しました。
ありがとうございました。

よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-01-10 11:07
引用:

メニュー画面もJSFなのですが・・・なぜなのでしょうか・・・


メニュー画面から入力画面へJSFのnavigation-ruleを使って遷移していますか?
単純なhtmlリンクで遷移しているのでは?
1

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