了解 JSF2 中的闪存范围



据我了解,在人脸请求生命周期中放置在Flash范围内的对象将可用于下一个人脸请求生命周期,然后清除。

假设我有两页:

第01页.xhtml

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

页01豆 :

@ManagedBean
@RequestScoped
public class Page01Bean {
        public void action(){
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("fooKey", "fooValue");
        }
}

页02.xhtml

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

因此,当单击page01.xhtml中的按钮时,人脸请求生命周期(例如生命周期A)开始,并将值设置为名为fooKey的键下的闪存

然后我打开另一个浏览器选项卡并浏览page02.xhtml.另一个面孔请求生命周期(比如生命周期B)开始呈现这个页面。我期望生命周期 B 可以访问其前一个生命周期的闪存范围(即生命周期 A)并在page02.xhtml中显示fooValue。但是,它什么也不显示。

请纠正我对本示例中闪光灯范围的误解。非常感谢

简而言之,存储在闪存范围内的变量将在重定向后幸存下来,之后它们将被丢弃。这在实现 Post-Redirect-Get 模式时非常有用。

如果您尝试通过重定向导航到另一个页面并在加载时访问属性,它们将在那里。完成该请求后,闪存中的值将被丢弃。例如:

您在 page1 中.xhtml并且您有一个命令链接,它使用类似这样的方法重定向到新页面(注意:我将使用隐式导航)。

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

呈现 pageB.xhtml 时,可以通过 EL 表达式访问这些值,例如

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

这将显示我们之前在navigateToPageB中保存的"Hello World!"字符串。

至于您的问题,通过在资源管理器中打开一个新选项卡,您不会访问在上一个选项卡上访问的相同上下文,因此您的变量将在那里不可用。

之前的答案是正确的,但为了完整起见,我想说在所有这些东西的 Mojarra 实现中存在很多问题,但最终他们实现了使其在 Mojarra 2.1.27 和 2.2.5 版本中正常工作。

正如@Gamb所说,闪存示波器的目的是保持参数在重定向内部映射的活跃状态。如果需要,我们还可以使参数保持更长时间。除了上述方式,FacesContext#getCurrentInstance#getExternalContext#getFlash#put,还有机会使用 <c:set /> 通过 EL 表达式设置参数。我在 SSCCE 之后实施了一个基本测试,它使用两个视图显示了更广泛的选项:

豆1

@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";
    }
}

页1.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>

豆2

@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");
    }
}

页2.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>

另请参阅:

  • JSF 闪存文档
  • 当用户手动重新加载视图时保留闪光灯参数

相关内容

  • 没有找到相关文章

最新更新