从闪存中删除JSF消息

egb*_*kul 9 jsf primefaces jsf-2 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";
 }
Run Code Online (Sandbox Code Playgroud)

我使用ap:growl组件在"发布"页面上显示我的消息.到现在为止还挺好.

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

我尝试过类似的东西:

<c:set target="#{flash}" property="keepMessages" value="false" />
Run Code Online (Sandbox Code Playgroud)

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

该消息将被保留并重新显示.如果我删除flash.setKeepMessages(true); 从上面的代码,然后没有显示任何内容.

我究竟做错了什么?

Arj*_*jms 7

我确实在JBoss AS 6上遇到了与Mojarra 2.0.3和Mojarra 2.1.1完全相同的问题.闪存只能存在一次重定向,但在实践中并不总是如此.

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

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

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

  1. 在someView上进行回发后,将继续显示flash面部消息
  2. 在向完全不同的页面发出干净请求后,还会显示面部消息
  3. 再次通过添加faces消息的代码后,您将在someView上获得两条相同的消息

问题2可以通过认识到闪存范围是基于cookie的(至少在Mojarra中)来解释.似乎很少有人理解其固有的问题.我发现了这个相关的问题,但它没有答案:Flash范围是否没有竞争条件?

此外,当试图重现问题时,我有大约2/3的机会实际再现它.有时它确实只能在单个重定向中存活,有时它会在几次刷新后消失(基于时间等等?)并且有时它只是坚持下去并且摆脱它的唯一方法是重新启动我的服务器(!).

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

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

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

POST Response
Set-Cookie csfcfc=_50Xfr

GET Response
Set-Cookie csfcfc=50Xfn_51Xfn
Run Code Online (Sandbox Code Playgroud)

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

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

POST Response
Set-Cookie csfcfc=_50Xfn
Run Code Online (Sandbox Code Playgroud)

消息现在消失了.

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

POST Response
Set-Cookie  csfcfc=_52Xfn
Run Code Online (Sandbox Code Playgroud)

而且,消息又回来了:(

如果我再次提交表格:

POST Response
Run Code Online (Sandbox Code Playgroud)

没有更多的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在重定向之后的GET请求的上下文中,可以假设isIsRedirect将返回true,但它返回false.这可能是一个本地问题,我将进一步调查.

值得注意的是,根据以下内容,cookie值实际上可能具有一定的含义:

 FirstTimeThru("f"),
 SecondTimeThru("s"),
 IsRedirect("r"),
 IsNormal("n");
Run Code Online (Sandbox Code Playgroud)

所以第一个cookie(_50Xfr)是a FirstTimeThru和a IsRedirect.