Mojarra 2.0.3 と Mojarra 2.1.1 の両方を使用する JBoss AS 6 でもまったく同じ問題が発生しました。フラッシュは 1 回のリダイレクトのみ存続する必要がありますが、実際には常に存続するとは限りません。
アクション メソッドには、基本的に同じコードがあります。
// [add global faces message]
FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
return "/someView.xhtml?faces-redirect=true";
問題の 3 つの症状が見られます。
- someView でポストバックを実行した後、フラッシュ フェース メッセージが表示され続ける
- 全く別のページへのクリーンリクエストの後、顔のメッセージも表示されます
- Faces メッセージを追加するコードをもう一度実行すると、someView で同じメッセージが 2 つ表示されます。
問題 2 は、フラッシュ スコープが Cookie ベースであることを認識することで説明できます (少なくとも Mojarra では)。それに固有の問題を理解している人は比較的少ないようです。この関連する質問を見つけましたが、答えがありません: Is Flash scope free of race conditions?
また、問題を再現しようとすると、実際に再現できる可能性は約 2/3 です。実際に1回のリダイレクトでしか生き残れない場合もあれば、数回の更新(時間ベースなど?)の後に消えてしまう場合もあれば、そのまま残り、サーバーを再起動するしかそれを取り除く唯一の方法(!)もあります。
多分私はどこかで何か間違ったことをしていますか?
Cookie が設定されているのを観察したところ、次のことに気付きました。
リダイレクトを行うアクションを最初にトリガーした後:
POST Response
Set-Cookie csfcfc=_50Xfr
GET Response
Set-Cookie csfcfc=50Xfn_51Xfn
ここで注意すべきことは、リダイレクトの GET リクエストからのレスポンスが再び Cookie を設定することです。フラッシュスコープの場合、ここで Cookie を削除する必要があると考えてください。
リダイレクトされたビューでフォームを送信すると、次のことが起こります。
POST Response
Set-Cookie csfcfc=_50Xfn
メッセージはなくなりました。
ただし、フォームをもう一度送信すると、次のことが起こります。
POST Response
Set-Cookie csfcfc=_52Xfn
そして、メッセージが戻ってきました:(
フォームを再度送信すると:
POST Response
Set-Cookie ヘッダーはなくなり、メッセージは再びなくなりました。フォームを送信し続けると、最後の Cookie (csfcfc=_52Xfn) がサーバーに送信され続けますが、新しい Cookie が設定されなくなり、メッセージが表示されなくなります。
編集:
デバッグ中に、ELFlash.java (Mojarra 2.0.3) のクリティカル セクションに遭遇しました。
void saveAllMessages(FacesContext context) {
// take no action on the GET that comes after a REDIRECT
Map<Object, Object> contextMap = context.getAttributes();
PreviousNextFlashInfoManager flashManager;
if (null == (flashManager = getCurrentFlashManager(contextMap, true))) {
return;
}
if (flashManager.getPreviousRequestFlashInfo().isIsRedirect()) {
return;
}
}
リダイレクトに続く GET リクエストのコンテキストでは、isIsRedirect が true を返すと思われるかもしれませんが、false を返しました。これはローカルの問題である可能性があり、さらに調査します。
興味深いことに、次のように、Cookie の値が実際には何らかの意味を持っている可能性があります。
FirstTimeThru("f"),
SecondTimeThru("s"),
IsRedirect("r"),
IsNormal("n");
したがって、最初の Cookie (_50Xfr) は aFirstTimeThru
と aIsRedirect
です。