7

I'm developing JSF 2 web application and using implicit navigation from page to page specifying outcome values and changing url values. I also have some Ajax requests to be able to make changes in some pages without having to submit everything.

My problem comes when, for example, I edit a user's data and save the changes. Managed Bean saves user data and return an String to navigate to the user list. When user is properly saved, a FacesMessage is added before the action method finishes.

Button

<p:commandButton value="#{msg.UPDATE}" action="#{manager.actionSave}"
            ajax="false" />

Code into the method

FacesContext.getCurrentInstance().addMessage(clientId, 
    new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));

However, and even I have an <h:messages /> tag in my main page, nothing is displayed there.

Aritz
  • 30,971
  • 16
  • 136
  • 217
  • 2
    You'll need to persist the messages yourself in the flash scope. See [this](http://stackoverflow.com/a/10369601) – kolossus Jan 09 '13 at 17:33
  • possible duplicate of [Passing a FacesMessage to the next page](http://stackoverflow.com/questions/12481506/passing-a-facesmessage-to-the-next-page) – Kowser Oct 13 '13 at 11:18

1 Answers1

11

The problem symptoms suggests that you're navigating by a redirect instead of a (default) forward by either the faces-redirect=true parameter in the outcome, or the <redirect/> entry in the navigation case, if you're still using legacy navigation rules in faces-config.xml.

Faces messages are request scoped and are thus only available in the resource served by the current request. When navigating by a redirect, you're basically instructing the webbrowser to create a brand new request on the given URL. The faces messages are not available in that request at all.

If redirecting is really mandatory, e.g. to accomplish the POST-Redirect-GET pattern — which is a Good Thing —, then you need to store the message in the flash scope. You can do that by calling Flash#setKeepMessages(), passing true.

context.addMessage(clientId, message);
context.getExternalContext().getFlash().setKeepMessages(true);

Note that this will fail if you're using a Mojarra version older than 2.1.14 and are redirecting to a resource in a different base folder. See also issue 2136.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • That's the right way, thanks @BalusC. By the way, is there a way to do it from a configuration file or something like that? Basically to prevent calling the method for every single message I add. – Aritz Jan 10 '13 at 09:42
  • 2
    There's nothing. Just use an utility class for this. OmniFaces offers [`Messages`](https://showcase-omnifaces.rhcloud.com/showcase/utils/Messages.xhtml) class for this. E.g. `Messages.addFlashInfo(clientId, msg);` – BalusC Jan 10 '13 at 11:50
  • Will give it a try. Just wanted to point that as I'm using PrettyFaces for navigation, it's always according to the POST-Redirect-GET pattern. http://ocpsoft.org/support/prettyfaces-users/how-to-do-post-redirect-get-after-action-with-prettyfaces – Aritz Jan 10 '13 at 11:59