【问题标题】:Removing JSF messages from the flash从闪存中删除 JSF 消息
【发布时间】:2011-03-21 13:34:18
【问题描述】:

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

 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 的页面上,我尝试从 backing bean 等中清除 flash。

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

我做错了什么?

【问题讨论】:

  • 这很奇怪,我正在做几乎完全相同的事情,但使用 h:messages 标签而不是 p:growl 标签显示消息。消息按我的预期消失了。可以尝试使用 h:messages 来代替,看看它是否有效?
  • 嗯,现在它正在工作。除了当用户按下后退按钮时,会显示消息,但我想这是正常行为。您是否尝试在第二页上将 flash.setKeepMessages() 设置为 false?
  • 这里有一个 JIRA 问题:java.net/jira/browse/JAVASERVERFACES-1751 不敢相信这仍然是开放的,因为它完全破坏了闪存范围的功能。
  • 这个(非常旧的)帖子报告了与您的问题类似的问题,并且与我在下面描述的完全相同的问题:java.net/projects/glassfish/lists/webtier/archive/2009-10/… Ed Burns 回答说他会做出反应,但似乎他从来没有这样做过。

标签: jsf jsf-2 primefaces flash-scope


【解决方案1】:

【讨论】:

    【解决方案2】:

    尝试将属性 redisplay 设置为 false:

    <p:growl redisplay="false"/>
    

    【讨论】:

      【解决方案3】:

      在使用 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 中)来解释。似乎很少有人理解它的内在问题。我找到了这个相关的问题,但没有答案: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。

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

      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) 是 FirstTimeThruIsRedirect

      【讨论】:

      • ELFlash 中的评论说:Any entries put into the "next" flash map on request N will be expired at the end of request N+1.,但这似乎从未发生过。我还希望 JSF 在此请求 N+1 处写出一个空 cookie,以便将其从客户端中删除,但这也永远不会发生。
      猜你喜欢
      • 2012-08-19
      • 2012-06-13
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多