web-dev-qa-db-ja.com

JSF2のFlashスコープを理解する

私が理解したことから、facesリクエストのライフサイクルでFlashスコープ内に配置されたオブジェクトは、次のfacesリクエストのライフサイクルで利用可能になり、その後クリアされます。

2つのページがあるとします。

page01.xhtml

<h:form>
    <h:commandButton  action="#{page01Bean.action}" />
</h:form>

Page01Bean:

@ManagedBean
@RequestScoped
public class Page01Bean {

        public void action(){
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("fooKey", "fooValue");
        }

}

page02.xhtml

<h:outputText value="#{flash.fooKey}"/> 

そのため、page01.xhtmlがクリックされると、facesリクエストのライフサイクル(ライフサイクルAなど)が開始され、fooKeyというキーの下のフラッシュに値が設定されます。

次に、別のブラウザタブを開き、page02.xhtml。別の人は、リクエストライフサイクル(ライフサイクルBなど)がこのページのレンダリングを開始します。ライフサイクルBが以前のライフサイクルのフラッシュスコープ(つまり、ライフサイクルA)にアクセスし、fooValuein page02.xhtml。ただし、何も表示されません。

この例題のフラッシュスコープについて誤解している点を修正してください。本当にありがとう

30
Ken Chan

つまり、フラッシュスコープに格納された変数はリダイレクト後も存続し、その後破棄されます。これは、Post-Redirect-Getパターンを実装するときに非常に便利です。

リダイレクトによって別のページに移動し、ロード時に属性にアクセスしようとすると、それらはそこにあります。その要求が行われた後、フラッシュ内の値は破棄されます。例えば:

Page1.xhtmlにいて、このようなメソッドで新しいページにリダイレクトするcommandLinkがあります(注:暗黙的なナビゲーションを使用します)。

public String navigateToPageB() {
    FacesContext.getCurrentInstance().getExternalContext().getFlash().put("param1", "Hello World!");
    return "pageB?faces-redirect=true";
}

PageB.xhtmlがレンダリングされると、次のようなEL式でこれらの値にアクセスできます。

<h:outputLabel value="#{flash['param1']}" />

「Hello World!」が表示されます前にnavigateToPageBで保存した文字列。

質問に関しては、Explorerで新しいタブを開くと、前のタブでアクセスしていたのと同じコンテキストにアクセスしていないため、変数はそこで使用できなくなります。

33
Fritz

前の答えは正しいですが、完全を期すために、Mojarraの実装ではこのすべてのもので 多くの問題 があったと言いたいのですが、最終的にはMojarra 2.1.27で正しく動作するようになりましたおよび2.2.5バージョン。

@Gambが言うように、フラッシュスコープの目的は、リダイレクトを越えて内部的にマッピングするパラメーターを維持することです。必要に応じて、パラメーターをより長く維持することもできます。上記の方法とは別に、FacesContext#getCurrentInstance#getExternalContext#getFlash#put、EL式を使用してパラメータを設定する機会もあります。 <c:set />[〜#〜] sscce [〜#〜] の後に基本的なテストを実装しました。これは、2つのビューを使用して、より広範なオプションを表示します。

Bean1

@ManagedBean
@ViewScoped
public class Bean1 implements Serializable {

    /**
     * Just takes the given param, sets it into flash context and redirects to
     * page2
     * 
     * @param inputValue
     * @return
     */
    public String goPage2(String inputValue) {
        FacesContext.getCurrentInstance().getExternalContext().getFlash()
                .put("param", inputValue);
        return "page2?faces-redirect=true";
    }

}

page1.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://Java.Sun.com/jsf/html"
    xmlns:ui="http://Java.Sun.com/jsf/facelets"
    xmlns:c="http://Java.Sun.com/jsp/jstl/core">
<h:head />
<h:body>

    <!-- Sets the first flash param at the action method, which redirects to page 2 -->
    <h:form>
        <h:inputText value="#{inputValue}" />
        <h:commandButton action="#{bean1.goPage2(inputValue)}"
            value="Go Page 2" />
    </h:form>

    <!-- Sets the second flash param -->
    <c:set target="#{flash}" property="param2" value="Myparam2" />

    <!-- Tries to retrieve both of the params. 
    Note none of them is displayed at the first page hit.
    If page refreshed, the second param which has been already set 
    using c:set above, will be displayed -->
    <p>Param1: #{flash['param']}</p>
    <p>Param2: #{flash['param2']}</p>
</h:body>
</html>

Bean2

@ManagedBean
@ViewScoped
public class Bean2 implements Serializable {

    public String getParam() {
        /**
         * Takes the parameter from the flash context
         */
        return (String) FacesContext.getCurrentInstance().getExternalContext()
                .getFlash().get("param");
    }

}

page2.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://Java.Sun.com/jsf/html"
    xmlns:ui="http://Java.Sun.com/jsf/facelets"
    xmlns:f="http://Java.Sun.com/jsf/core">
<h:head />
<!-- This page just displays the received params -->
<h:body>
    <!-- Different ways to retrieve the params from the flash scope -->
    <p>Param1: #{bean2.param}</p>
    <p>Param1: #{flash.param}</p>
    <p>Param1: #{flash['param']}</p>
    <p>Param2: #{flash['param2']}</p>

    <!-- Keep the first param for next redirection -->
    #{flash.keep.param}

    <!-- Return to page1 and see how the first param is retained -->
    <h:button outcome="page1?faces-redirect=true" value="return to 1" />
</h:body>
</html>

以下も参照してください:

24
Xtreme Biker