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");
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.)
Now how can I add FacesMessage so that it is visible in the redirected (scenario.xhtml) page?
This seems to be a timing problem. This listener method is invoked during the
preRenderViewevent. According to the source code ofELFlash(Mojarra’sFlashimplementation as returned byExternalContext#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:Here are the relevant lines from
ELFlash:The
maybeWriteCookiewould 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).This is an unfortunate corner case. This
ELFlashlogic makes sense, but this isn’t what you actually want. Basically you need to add the message duringINVOKE_APPLICATIONphase instead. There is however no such event aspostInvokeAction. With the new JSF 2.2<f:viewAction>tag it should be possible as it really runs during invoke application phase.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.Now you need somewhere a hook to publish this event. The most sensible place is a
PhaseListenerlistening on after phase ofINVOKE_APPLICATION.If you register it as follows in
faces-config.xmlthen you’ll be able to use the new event as follows
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
InvokeActionEventListenershowcase example.