使用ExternalContext.redirect()将面孔消息添加到重定向页面 [英] Adding faces message to redirected page using ExternalContext.redirect()

查看:100
本文介绍了使用ExternalContext.redirect()将面孔消息添加到重定向页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ExternalContext.redirect(String); 方法将用户重定向到另一个页面:

I am using ExternalContext.redirect(String); method to redirect user to another page:

FacesContext.getCurrentInstance().addMessage(new FacesMessage("Bla bla bla..."));
FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/scenario.xhtml");

正如Matt Handy在回答中提到的那样,我使用了 Flash.setKeepMessages(true); ,但它似乎不适用于ExternalContext.redirect. (尽管当我通过从bean的action方法返回页面名称进行重定向时,它可以工作.)

As Matt Handy mentioned in his answer, I used Flash.setKeepMessages(true); but it does not seem to work with ExternalContext.redirect. (Although it works when I redirect by returning a page name from bean's action method.)

现在如何添加FacesMessage,以使其在重定向的(scenario.xhtml)页面中可见?

Now how can I add FacesMessage so that it is visible in the redirected (scenario.xhtml) page?

推荐答案

这似乎是一个计时问题.在preRenderView事件期间调用此侦听器方法.根据ELFlash的源代码(Mojarra的 实现(由ExternalContext#getFlash()返回),结果表明当您当前处于渲染响应阶段且尚未为当前请求设置Flash Cookie时,它不会设置Flash Cookie :

This seems to be a timing problem. This listener method is invoked during the preRenderView event. According to the source code of ELFlash (Mojarra's Flash implementation as returned by ExternalContext#getFlash()) it turns out that it won't set the flash cookie when you're currently sitting in the render response phase and the flash cookie hasn't been set yet for the current request:

以下是ELFlash中的相关行:

if (currentPhase.getOrdinal() < PhaseId.RENDER_RESPONSE.getOrdinal()) {
    flashInfo = flashManager.getPreviousRequestFlashInfo();
} else {
    flashInfo = flashManager.getNextRequestFlashInfo(this, true);
    maybeWriteCookie(context, flashManager);
}

maybeWriteCookie仅在第二次需要通过Flash Cookie时(即,当重定向的页面又重定向到另一个页面时)设置cookie.

The maybeWriteCookie would only set the cookie when the flash cookie needs to be passed through for the second time (i.e. when the redirected page in turn redirects to another page).

这是一个不幸的极端情况.这种ELFlash逻辑很有意义,但这并不是您真正想要的. 基本上,您需要在INVOKE_APPLICATION阶段添加消息.但是,没有像postInvokeAction这样的事件.有了新的JSF 2.2 <f:viewAction>标记,它应该可以实现,因为它实际上是在调用应用程序阶段运行的.

This is an unfortunate corner case. This ELFlash logic makes sense, but this isn't what you actually want. Basically you need to add the message during INVOKE_APPLICATION phase instead. There is however no such event as postInvokeAction. With the new JSF 2.2 <f:viewAction> tag it should be possible as it really runs during invoke application phase.

<f:viewAction action="#{bean.onload}" />

只要您还没有使用JSF 2.2,就需要寻找其他方法.最简单的方法是创建自定义 ComponentSystemEvent .

As long as you're not on JSF 2.2 yet, you'd need to look for alternate ways. The easiest way would be to create a custom ComponentSystemEvent.

@NamedEvent(shortName="postInvokeAction")
public class PostInvokeActionEvent extends ComponentSystemEvent {

    public PostInvokeActionEvent(UIComponent component) {
        super(component);
    }

}

现在,您需要在某个位置发布此事件.最明智的位置是 PhaseListener INVOKE_APPLICATION阶段之后收听.

Now you need somewhere a hook to publish this event. The most sensible place is a PhaseListener listening on after phase of INVOKE_APPLICATION.

public class PostInvokeActionListener implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.INVOKE_APPLICATION;
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        // NOOP.
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        FacesContext context = FacesContext.getCurrentInstance();
        context.getApplication().publishEvent(context, PostInvokeActionEvent.class, context.getViewRoot());
    }

}

如果您在faces-config.xml

<lifecycle>
    <phase-listener>com.example.PostInvokeActionListener</phase-listener>
</lifecycle>

然后您将可以按以下方式使用新事件

then you'll be able to use the new event as follows

<f:event type="postInvokeAction" listener="#{bean.onload}" />


更新也可以在JSF实用程序库 OmniFaces 中找到,因此您不必需要自制的一个.另请参见 InvokeActionEventListener展示示例.


Update this is also available in the JSF utility library OmniFaces, so you don't need to homebrew the one and other. See also the InvokeActionEventListener showcase example.

这篇关于使用ExternalContext.redirect()将面孔消息添加到重定向页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆