【问题标题】:Why is flash.keep() removing the key if it is in a bean but not in EL in Facelets page?为什么 flash.keep() 如果它在一个 bean 中而不是在 Facelets 页面的 EL 中,它会删除它?
【发布时间】:2016-06-24 19:12:55
【问题描述】:

所以我有这个非常小的 JSF 示例:

<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <title>Index</title>
</h:head>
<h:body>
    <h:form>
        <h:commandButton action="#{reqScopedBackingBean.foo()}" value="Submit"/>
    </h:form>
</h:body>
</html>

foo 的实现如下所示:

package biz.tugay.jsftags;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@RequestScoped
public class ReqScopedBackingBean {
    public String foo() {
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("message", "Success!!");
        return "hello?faces-redirect=true";
    }
}

最后hello.xhtml如下:

<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <title>Hello</title>
</h:head>
<h:body>
    <h:outputText value="#{flash.keep.message}"/>
</h:body>
</html>

在上面的例子中,当我点击提交时,我将被重定向到 hello.xhtml 并看到“成功!!”文字就好了。当我刷新页面时,我仍然会看到该消息,因为我正在调用如下所示的 keep 方法:

#{flash.keep.message}

现在转到另一个例子:

index.xhtml 和 ReqScopedBackingBean 是一样的,但是这次的 hello.xhtml 如下:

<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <title>Hello</title>
</h:head>
<h:body>
    #{otherBean.pullValuesFromFlash()}
    <h:outputText value="#{otherBean.message}"/>
</h:body>
</html>

OtherBean.java如下:

@ManagedBean
@RequestScoped
public class OtherBean {

    private String message;

    public void pullValuesFromFlash() {
        final Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
        flash.keep("message");
        final String message = (String) flash.get("message");
        setMessage(message);
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

我希望行为与第一个示例相同。但是,当我在 hello.xhtml 上时,我不会看到成功消息。但是,如果我注释掉该行:

// flash.keep("message");

然后会出现消息(但在 hello.xhtml 上刷新不会像第一个示例那样重新显示成功消息)。

我的问题是,这里有什么区别?怎么样

#{flash.keep.message}

和不同的

flash.keep("message");
final String message = (String) flash.get("message");

?

【问题讨论】:

    标签: jsf jsf-2 flash-scope


    【解决方案1】:

    您遇到了 Flash#keep() 的 Mojarra 错误。基本上,Mojarra 不必要地removes 来自当前闪存范围的条目,然后再将其放入下一个闪存范围。

    如果您将逻辑重新排序如下,它将起作用。

    public void pullValuesFromFlash() {
        Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
        String message = (String) flash.get("message");
        flash.keep("message");
        setMessage(message);
    }
    

    根据issue 4167,我有fixed 这个错误。


    与具体问题无关,那些&lt;h:outputText&gt;s 是不必要的。您可以安全地删除它们以减少样板文件。另见Is it suggested to use h:outputText for everything?

    【讨论】:

      猜你喜欢
      • 2011-05-19
      • 2011-05-17
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多