从preRender导航后无法保留人脸消息 [英] Can't keep faces message after navigation from preRender
问题描述
在我的页面的preRender代码中,我添加面孔消息,然后按如下所示导航到另一个页面:
in my preRender code for a page i add faces message then make navigation to another page as follows:
if(error){
addMessageToComponent(null,"AN ERROR HAS OCCURRED");
FacesContext.getCurrentInstance().getExternalContext().getFlash()
.setKeepMessages(true);
navigateActionListener("myoutcome");
}
以及用于添加消息和导航的util方法是:
and the util methods for adding message and navigation are:
public static String getClientId(String componentId)
{
FacesContext context = FacesContext.getCurrentInstance();
UIViewRoot root = context.getViewRoot();
UIComponent c = findComponent(root, componentId);
return c.getClientId(context);
}
public static UIComponent findComponent(UIComponent c, String id)
{
if (id.equals(c.getId())) { return c; }
Iterator<UIComponent> kids = c.getFacetsAndChildren();
while (kids.hasNext())
{
UIComponent found = findComponent(kids.next(), id);
if (found != null) { return found; }
}
return null;
}
/**
* @param componentId
* : the id for the jsf/primefaces component without formId:
* prefix. <br>
* if you use null then the message will be added to the
* h:messages component.
**/
public static void addMessageToComponent(String componentId, String message)
{
if (componentId != null)
componentId = GeneralUtils.getClientId(componentId);
FacesContext.getCurrentInstance().addMessage(componentId,
new FacesMessage(message));
}
public static void navigateActionListener(String outcome)
{
FacesContext context = FacesContext.getCurrentInstance();
NavigationHandler navigator = context.getApplication()
.getNavigationHandler();
navigator.handleNavigation(context, null, outcome);
}
但是邮件不会保存,因此重定向后不会显示.
but messages are not saved and so it doesn't appear after redirect.
请提出解决方法.
推荐答案
preRenderView
事件在RENDER_RESPONSE
阶段的最开始运行.指示Flash
范围保留消息为时为时已晚.您最多可以在INVOKE_APPLICATION
阶段进行此操作.
The preRenderView
event runs in the very beginning of the RENDER_RESPONSE
phase. It's too late to instruct the Flash
scope to keep the messages. You can do this at the latest during the INVOKE_APPLICATION
phase.
由于没有标准的JSF组件系统事件,您需要进行自制程序:
Since there's no standard JSF component system event for this, you'd need to homebrew one:
@NamedEvent(shortName="postInvokeAction")
public class PostInvokeActionEvent extends ComponentSystemEvent {
public PostInvokeActionEvent(UIComponent component) {
super(component);
}
}
要发布此内容,您需要PhaseListener
:
To publish this, you need a PhaseListener
:
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>
您将可以按以下方式使用新事件:
You'll be able to use the new event as follows:
<f:event type="postInvokeAction" listener="#{bean.init}" />
您只需要确保您至少具有<f:viewParam>
,否则JSF根本不会进入调用的阶段.
You only need to make sure that you've at least a <f:viewParam>
, otherwise JSF won't enter the invoked phase at all.
JSF实用程序库 OmniFaces 已经支持该事件,而preInvokeAction
事件则是现成的.另请参见展示页面,该页面还演示了设置面部消息以进行重定向.
The JSF utility library OmniFaces already supports this event and the preInvokeAction
event out the box. See also the showcase page which also demonstrates setting a facesmessage for redirect.
这篇关于从preRender导航后无法保留人脸消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!