从闪存中删除 JSF 消息

发布于 2024-09-11 23:35:48 字数 811 浏览 8 评论 0原文

我有一个页面可以执行某些操作,当用户单击按钮时,用户会被重定向到另一个页面并显示一条消息。这是我的代码:

 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 的页面上,我尝试清除支持 bean 等的闪存。

该消息被保留并再次显示。如果我删除 flash.setKeepMessages(true);从上面的代码来看,什么也没有显示。

我做错了什么?

I have one page that does something and when the user clicks a button, the user is redirected to another page and a message is displayed. Here is my code:

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

I use a p:growl component which displays my message on the "releases" page. So far so good.

But then on any subsequent page that has p:growl (or if I go to another page and go back) the message is displayed again and again and I can't kill it.

I tried something like:

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

on the page that has the p:growl, I tried clearing the flash from the backing bean etc.

The message is retained and displayed all over again. If I remove flash.setKeepMessages(true); from the code above then nothing is displayed.

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白首有我共你 2024-09-18 23:35:48

我在 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";

我看到了问题的三个症状:

  1. 在 someView 上进行回发后,flash faces 消息不断显示
  2. 在对完全不同的页面发出干净的请求后,face 消息是再次查看
  3. 添加 faces 消息的代码后,您将在 someView 上收到两条相同的消息。

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

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

也许我在某个地方做错了什么?

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

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

POST Response
Set-Cookie csfcfc=_50Xfr

GET Response
Set-Cookie csfcfc=50Xfn_51Xfn

这里需要注意的是,重定向的 GET 请求的响应再次设置了 cookie。您可能会认为,对于闪存范围,需要在此处删除 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.1) 中的关键部分。 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) 是一个 FirstTimeThru 和一个 IsRedirect

I did get the exact same problem on JBoss AS 6 with both Mojarra 2.0.3 and Mojarra 2.1.1. The flash should survive only one redirect, but in practice it not always does.

In an action method I have basically the same code:

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

I've been seeing three symptoms of the problem:

  1. After doing a postback on someView, the flash faces message keeps being displayed
  2. After a clean request to a completely different page, the face message is also displayed
  3. After going again through the code that adds the faces message, you'll get two of the same messages on someView

Issue 2 can be explained by realizing that the flash scope is cookie based (at least in Mojarra). Relatively few people seem to understand the inherent problem with that. I've found this related question, but it has no answers: Is Flash scope free of race conditions?

Also, when trying to reproduce the problem I've got approximately a 2/3 chance of actually reproducing it. Sometimes it indeed only survives a single redirect, sometimes it's gone after a few refreshes (time based or so?) and sometimes it just sticks around and the only way to get rid of it is restarting my server(!).

Maybe I'm doing something wrong somewhere?

Observing the cookies being set, I noticed the followed:

After initially triggering the action that does the redirect:

POST Response
Set-Cookie csfcfc=_50Xfr

GET Response
Set-Cookie csfcfc=50Xfn_51Xfn

The thing to notice here is that the response from the GET request for the redirect again sets a cookie. You want think that for a flash scope the cookie would need to be deleted here.

If I submit a form on the view towards I'm redirected, the following happens:

POST Response
Set-Cookie csfcfc=_50Xfn

The message is now gone.

However, when I submit the form once more, the following happens:

POST Response
Set-Cookie  csfcfc=_52Xfn

And, the message is back :(

If I again submit the form:

POST Response

There is no more Set-Cookie header and the message in once again gone. If I continue submitting the form, the last cookie (csfcfc=_52Xfn) keeps being send to the server, but there are no more new cookies being set and no messages are displayed.

Edit:

During debugging I came across a critical section in 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;
    }
}

During the context of the GET request following the redirect, one would suppose isIsRedirect would return true, but it returned false. This could be a local problem, that I'm going to investigate further.

Interesting to note is perhaps that the cookie values actually have some meaning, according to the following:

 FirstTimeThru("f"),
 SecondTimeThru("s"),
 IsRedirect("r"),
 IsNormal("n");

So the first cookie (_50Xfr), is a FirstTimeThru and a IsRedirect.

故事还在继续 2024-09-18 23:35:48
春风十里 2024-09-18 23:35:48

尝试将属性 redisplay 设置为 false:

<p:growl redisplay="false"/>

Try setting property redisplay to false:

<p:growl redisplay="false"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文