【问题标题】:How to keep JSF flash scope parameters on page reload?如何在页面重新加载时保留 JSF 闪存范围参数?
【发布时间】:2014-09-20 14:52:51
【问题描述】:

我使用 Flash 范围在 @viewscoped 控制器之间传递设置对象。但是,如果我在其中一个上重新加载页面,则闪存映射为空,并且设置对象未初始化。是否可以在页面重新加载时保持 Flash 范围?

我用于存储/检索设置的源代码:

FistPage.xhtml

...
<p:commandButton value="next"
    action="#{firstPageController.transferConfig}"  
    process="@this" />
...

FirstPageController.java

@ManagedBean(name = "firstPageController")
@ViewScoped
public class FirstPageController {
...
public String transferConfig() {
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("searchConfig",   searchConfig);
return "/secondPage.xhtml?faces-redirect=true";
}
...
}

SecondPage.xhtml

...
<h:outputLabel value="value">
    <f:event type="preRenderComponent" listener="#{secondPageController.onPageLoad()}"/>
</h:outputLabel>
...

SecondPageController.java

@ManagedBean(name = "secondPageController")
@ViewScoped
public class SecondPageController {
    ...
    public void onPageLoad() 
    {
        flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();

        searchConfig = ((SearchFilterConfig) flash.get("searchConfig"));

        flash.putNow("searchConfig", searchConfig);

        flash.keep("searchConfig");
    }
    ...
}

我使用 Mojarra 2.1.29

谢谢

【问题讨论】:

  • 你从哪里调用这个方法?如果参数不在地图中,这将无济于事......您是否在其他任何地方记录它?
  • 我刚刚意识到您根本没有执行重定向以转到您的第二个视图。你能看到地址栏中的 url 改变了吗?
  • 是的,我可以。我在上面的代码中更改了它。仅当我使用 update="@all" 重新加载 secondPage 或对 secondPage 执行操作时才会出现问题
  • 它们是不同的东西。第一个是对视图的GET 请求,您所说的第二个是对同一视图的回发。第二个可以避免保留闪存参数或将其存储在@ViewScoped
  • @Alex:使用 flash 范围对@ViewScoped bean 进行同一页面重新加载有什么意义?您可以将变量存储为该 bean 的实例变量,并且在重新加载时它仍然存在

标签: jsf-2 flash-scope


【解决方案1】:

我刚刚在 Playground 项目中进行了一些测试,并意识到即使您再次 GET 使用 @987654325,也可以保持 Flash 参数的状态 @。 JSF docs 是这样解释的:

即使在包含&lt;redirect /&gt;&lt;navigation-case&gt; 的情况下,实现也必须确保保留闪存的正确行为。即使在同一会话上的相邻 GET 请求的情况下,实现也必须确保保留闪存的正确行为。这允许 Faces 应用程序充分利用 Post/Redirect/Get 设计模式。

这里有一个不错的基本测试用例:

page1.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head />
<h:body>
    <h:form>
        <h:button id="nextButton" value="Next (button)" outcome="page2.xhtml" />
        <c:set target="#{flash}" property="foo" value="bar" />
    </h:form>
</h:body>
</html>

page2.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
<head />
<body>foo = #{flash.keep.foo}
</body>
</html>

只需打开第一页,然后单击将您重定向到第二页的按钮。然后根据需要多次刷新第二页,您会发现参数持续存在。


在 Mojarra 2.2.6 中测试

【讨论】:

  • 您好,您知道在托管 bean 中获取持久化 flash 参数值吗?
  • @EvaMariam,见this answer
  • 我不想在前端 (ui) 中显示 flash 参数。它应该在手动重新加载时在 bean 中重用,以从 db 获取其他值。你能看看this吗?
  • 这里发生了什么黑魔法? keep 是一个没有返回类型并接受 String 作为参数的方法,但是您在没有参数的情况下调用它并使用 .foo 链接它?
  • @KorayTugay,没有。你有一些关于这个here 的文档。或多或少:Parameters: key - if argument key is the name of an entry previously stored to the flash on this traversal through the lifecycle via a call to putNow(java.lang.String, java.lang.Object), or to a set to the EL expression #{flash.now.&lt;key&gt;}, or to the request Map, to be promoted to the flash as if a call to put() or a set to the expression #{flash.&lt;key&gt;} was being called.。似乎是与 EL 相关的功能。
猜你喜欢
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-14
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
相关资源
最近更新 更多