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.
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);
}
}
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());
}
}
After registering it as follows in 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}" />
You only need to make sure that you've at least a <f:viewParam>
, otherwise JSF won't enter the invoked phase at all.
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…