0

JSF の FlashScope に問題があります。リダイレクトは、呼び出し元のページと同じベース パスを指す必要があることに注意してください。

私の場合、クライアントが電子メールからリンクをクリックするとアクションが初期化され、バッキング Bean を含む .xhtml (preRenderView イベントがある) ページが読み込まれ、渡されたパラメーターがチェックされます。パラメータが間違っている場合、メッセージを含む新しいページにリダイレクトする必要があります。

景色:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

    <f:metadata>
        <f:viewParam name="dummy" />
        <f:event listener="#{signupMaterialBean.initFromContext()}"
            type="preRenderView"></f:event>
    </f:metadata>

    <h:outputText value="#{signupMaterialBean.html}" escape="false"></h:outputText>

</ui:composition>

バッキング Bean:

public void initFromContext() {
    try {
        Map<String, String> params = facesContext.getExternalContext()
                .getRequestParameterMap();
        ...
    } catch (NullPointerException e) {      
        try {
            Message message = new Message();
            String msg = "Invalid parameters";
            message.setMessage(msg);

            JSFUtils.flashScope().put("message", message);

            facesContext.getExternalContext().redirect("message.xhtml");
            facesContext.responseComplete();
        } catch (IOException ioe) {
        }
    } catch (IOException e) {
    }
}

リダイレクトは機能しますが、FlashScope に保存されたメッセージはなくなりました。なぜフラッシュスコープが削除されているのか、それとも別の方法で削除されているのか考えていますか?

メッセージ.xhtml

    <ui:define name="head"></ui:define>

    <ui:define name="content">
        <div class="box-middle-content faded">
            <div class="message">
                <h:outputText escape="false" value="#{flash.message.message}"></h:outputText>
                <br />
                <p>
                    <h:outputText value="#{msgs['message.footer']}" escape="false" />
                </p>
            </div>
        </div>
    </ui:define>
</ui:composition>

JSFUtils

public class JSFUtils {
    public static Flash flashScope() {
        return (FacesContext.getCurrentInstance().getExternalContext()
                .getFlash());
    }
}

更新されたビュー:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:of="http://omnifaces.org/functions">

    <f:metadata>
        <f:viewParam name="dummy"></f:viewParam>
        <f:event type="postInvokeAction"
            listener="#{signupMaterialBean.initFromContext}" />
    </f:metadata>

    <h:outputText value="#{signupMaterialBean.html}" escape="false"></h:outputText>

</ui:composition>
4

1 に答える 1

4

フラッシュ スコープの<f:event type="preRenderView">アトリビュートを設定するには遅すぎます。JSF が現在レンダリング レスポンス フェーズにある場合、フラッシュ スコープを作成できません。基本的に、レンダリング レスポンス フェーズの前に、フラッシュ スコープ属性を設定する必要があります。という名前にもかかわらずpreRenderView、このイベントは実際には、レンダリング レスポンス フェーズ (最初の段階) で発生します

基本的に、INVOKE_ACTION フェーズでリスナー メソッドを呼び出す必要があります。これには標準<f:event>タイプがないため、自作する必要があります。これは、この回答で詳しく説明されています: can't keep faces message after navigation from preRender .

最終的には次のようになります。

<f:event listener="#{signupMaterialBean.initFromContext()}"
         type="postInvokeAction" />

このイベントはOmniFacesによってすでに提供されていることに注意してください。この問題を正確に処理するInvokeActionEventListenerショーケース ページも参照してください。


具体的な問題とは関係ありませんが、キャッチ オンNullPointerExceptionは巨大なコードの匂いです。そのような実行時例外をキャッチしないでください。nullchecking asif (foo != null)などを実行してそれらを防ぎます。また、それらの空のキャッチIOExceptionは非常に悪いです。throws IOExceptionそれらをすべて削除して、メソッドに追加するだけです。

さらに、リダイレクト パスの問題は Mojarra 2.1.14 以降で修正されています。したがって、そのバージョン以降、別のベースパスに安全にリダイレクトできます。

于 2012-11-22T14:06:50.400 に答える