jsf - 从闪存中删除JSF消息

标签 jsf jsf-2 primefaces flash-scope

我有一个页面在做某事,当用户单击一个按钮时,该用户将被重定向到另一页面,并显示一条消息。这是我的代码:

 public String confirm() {
    FacesContext context = FacesContext.getCurrentInstance();
    Flash flash = context.getExternalContext().getFlash();
    flash.setKeepMessages(true);
    FacesMessage msg = new FacesMessage("Succesful", "Release is confirmed!");
    context.addMessage(null, msg);
    return "/prot/expert/releases?faces-redirect=true";
 }

我使用p:growl组件,该组件在“发行”页面上显示我的消息。到现在为止还挺好。

但是随后在任何具有p:growl的页面上(或者如果我转到另一页面然后返回),该消息就会一次又一次地显示,而我无法将其杀死。

我尝试了类似的东西:
<c:set target="#{flash}" property="keepMessages" value="false" />

在具有p:growl的页面上,我尝试清除支持bean等中的闪存。

该消息将保留并再次显示。如果我删除flash.setKeepMessages(true);从上面的代码中,则什么也不会显示。

我究竟做错了什么?

最佳答案

我确实在Mojarra 2.0.3和Mojarra 2.1.1的JBoss AS 6上都遇到了完全相同的问题。闪存应仅能承受一次重定向,但实际上并非总是如此。

在 Action 方法中,我基本上具有相同的代码:

// [add global faces message]
FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
return "/someView.xhtml?faces-redirect=true";

我一直看到该问题的三个症状:
  • 在someView上执行回发后,闪烁面孔消息不断显示
  • 在彻底请求另一个完全不同的页面之后,还会显示面部消息
  • 再次遍历添加faces消息的代码后,您将在someView
  • 上获得两条相同的消息

    可以通过意识到Flash范围是基于cookie的(至少在Mojarra中)来解释问题2。相对而言,似乎很少有人了解其固有的问题。我发现了这个相关问题,但没有答案:Is Flash scope free of race conditions?

    另外,当尝试重现该问题时,我大约有2/3的机会实际重现该问题。有时它确实只能经受一次重定向,有时它在经过几次刷新后就消失了(基于时间?),有时它仍然存在,摆脱它的唯一方法是重新启动服务器(!)。

    也许我在某处做错了什么?

    观察正在设置的cookie,我注意到以下内容:

    最初触发执行重定向的操作后,请执行以下操作:
    POST Response
    Set-Cookie csfcfc=_50Xfr
    
    GET Response
    Set-Cookie csfcfc=50Xfn_51Xfn
    

    这里要注意的是,GET请求对重定向的响应再次设置了一个cookie。您想认为对于Flash作用域,此处需要删除cookie。

    如果我在重定向的 View 上提交表单,则会发生以下情况:
    POST Response
    Set-Cookie csfcfc=_50Xfn
    

    该消息现在消失了。

    但是,当我再次提交表单时,会发生以下情况:
    POST Response
    Set-Cookie  csfcfc=_52Xfn
    

    而且,消息又回来了:(

    如果我再次提交表格:
    POST Response
    

    没有更多的Set-Cookie header ,消息再次消失了。如果我继续提交表单,则最后一个cookie(csfcfc = _52Xfn)会继续发送到服务器,但是不会再设置新的cookie,也不会显示任何消息。

    编辑:

    在调试期间,我遇到了ELFlash.java(Mojarra 2.0.3)中的关键部分:
    void saveAllMessages(FacesContext context) {
        // take no action on the GET that comes after a REDIRECT
        Map<Object, Object> contextMap = context.getAttributes();
        PreviousNextFlashInfoManager flashManager;
        if (null == (flashManager = getCurrentFlashManager(contextMap, true))) {
            return;
        }
        if (flashManager.getPreviousRequestFlashInfo().isIsRedirect()) {
            return;
        }
    }
    

    在重定向之后的GET请求的上下文中,人们会假设isIsRedirect将返回true,但是它返回false。这可能是一个局部问题,我将进一步调查。

    有趣的是,根据以下内容,cookie值实际上可能具有某些含义:
     FirstTimeThru("f"),
     SecondTimeThru("s"),
     IsRedirect("r"),
     IsNormal("n");
    

    因此,第一个Cookie(_50Xfr)是FirstTimeThruIsRedirect

    关于jsf - 从闪存中删除JSF消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3343147/

    相关文章:

    css - 在 JSF 中通过 BooleanCheckBox 动态改变 styleClass

    jsf-2 - 在 j_spring_security_check 之后重定向

    jsf-2 - Primefaces 命令按钮客户端变量

    jsf-2 - p :tabView: direct link to tab

    java - 从 JSF 中的子类访问属性时出错

    jsf - h :selectOneMenu with user-defined object

    jsf - 自定义组件上的 ValueChangeListener 导致 PropertyNotFoundException

    css - 在 PrimeFaces 模板中显示页脚,当 p :layout is set to false 的全页时

    jsf - 如何使用拖放对 DataTable 中的行重新排序?

    ajax - 添加 <f :ajax> to <h:commandButton> 时,提交的表单值未在模型中更新