9

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

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

我使用 ap:growl 组件,它在“发布”页面上显示我的消息。到目前为止,一切都很好。

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

我试过类似的东西:

<c:set target="#{flash}" property="keepMessages" value="false" />

在有 p:growl 的页面上,我尝试从 backing bean 等中清除 flash。

该消息被保留并重新显示。如果我删除 flash.setKeepMessages(true); 从上面的代码然后什么都不会显示。

我究竟做错了什么?

4

3 回答 3

7

我确实在使用 Mojarra 2.0.3 和 Mojarra 2.1.1 的 JBoss AS 6 上遇到了完全相同的问题。flash 应该只能在一次重定向中存活,但实际上并非总是如此。

在一个动作方法中,我有基本相同的代码:

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

我一直看到这个问题的三个症状:

  1. 在 someView 上回发后,flash faces 消息一直显示
  2. 对完全不同的页面进行干净请求后,也会显示面部消息
  3. 再次浏览添加面孔消息的代码后,您将在 someView 上收到两条相同的消息

问题 2 可以通过意识到 flash 作用域是基于 cookie 的(至少在 Mojarra 中)来解释。似乎很少有人理解它的内在问题。我找到了这个相关的问题,但没有答案:Flash 范围是否没有竞争条件?

此外,当试图重现该问题时,我有大约 2/3 的机会实际重现它。有时它确实只能在一个重定向中幸存下来,有时它会在几次刷新后消失(基于时间左右?),有时它会一直存在,摆脱它的唯一方法是重新启动我的服务器(!)。

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

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

在最初触发执行重定向的操作后:

POST Response
Set-Cookie csfcfc=_50Xfr

GET Response
Set-Cookie csfcfc=50Xfn_51Xfn

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

如果我在我被重定向的视图上提交表单,则会发生以下情况:

POST Response
Set-Cookie csfcfc=_50Xfn

消息现在消失了。

但是,当我再次提交表单时,会发生以下情况:

POST Response
Set-Cookie  csfcfc=_52Xfn

而且,消息又回来了:(

如果我再次提交表格:

POST Response

没有更多的 Set-Cookie 标头,并且消息再次消失。如果我继续提交表单,最后一个 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) 是 aFirstTimeThru和 a IsRedirect

于 2011-06-19T17:43:05.640 回答
-2

尝试将属性重新显示设置为 false:

<p:growl redisplay="false"/>
于 2013-11-20T07:57:32.400 回答