在我的preRender代码页面中我添加了face消息,然后导航到另一个页面,如下所示:
if(error){
addMessageToComponent(null,"AN ERROR HAS OCCURRED");
FacesContext.getCurrentInstance().getExternalContext().getFlash()
.setKeepMessages(true);
navigateActionListener("myoutcome");
}
和添加消息和导航的util方法是:
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);
}
但邮件未保存,因此重定向后不会显示。
请告知如何解决这个问题。
答案 0 :(得分:4)
preRenderView
事件在RENDER_RESPONSE
阶段的最开始运行。 太晚指示Flash
范围保留消息。您最迟可以在INVOKE_APPLICATION
阶段执行此操作。
由于没有标准的JSF组件系统事件,你需要自制一个:
@NamedEvent(shortName="postInvokeAction")
public class PostInvokeActionEvent extends ComponentSystemEvent {
public PostInvokeActionEvent(UIComponent component) {
super(component);
}
}
要发布此内容,您需要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>
您将能够按如下方式使用新活动:
<f:event type="postInvokeAction" listener="#{bean.init}" />
你只需要确保你至少有一个<f:viewParam>
,否则JSF根本不会进入被调用的阶段。
JSF实用程序库OmniFaces已经支持此事件和preInvokeAction
事件。另请参阅the showcase page,其中还演示了为重定向设置facesmessage。