Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

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.

please advise how to fix that.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
849 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...