为什么flash.keep()删除键,如果它是在bean中,而不是在EL在Facelets页面



所以我有这个非常小的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>
在上面的例子中

,当我点击Submit时,我将被重定向到hello.xhtml,并看到"Success!!"文本。当我刷新页面时,我仍然会看到消息,因为我调用了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");

?

你已经击中了Flash#keep()的Mojarra bug。基本上,Mojarra没有必要在将条目放入下一个flash作用域之前将其从当前flash作用域中移除。

如果按照下面的顺序重新排列逻辑,它将工作。

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

我已经按照第4167期修复了这个错误。


与具体问题无关的,这些<h:outputText> s是不必要的。您可以安全地删除它们以减少样板文件。参见是否建议使用h:outputText来处理所有内容?

相关内容

  • 没有找到相关文章

最新更新