...
One common question about JSF is how to manage messages of various types, which are generated by JSF components and backing beans. This discussion is designed as an introduction to the topic and focused on entry to mid-level JSF users.
...
JSF message tags display messages which have been queued as the request is processed. Each message that is queued has a message priority which is one of the FacesMessage priorities defined in javax.faces.application.FacesMessage and are defined as
...
...
and can be either associated with a component or not. When a message is generated during processing, the component, validator or backing generating the message palces the message into one of the message queues where it can be accessed by the JSF during the rendering phase.
...
Messages (error/info/warn/fatal) can be enqueued by calling the FacesContext.getCurrentInstance().addMessage() method. Our requirements state that messages are displayed on all change in state as well as processing errors such as bad databases retrievals etc. which means that the majority of our pages need to be able to generate messages. To this end, we found it is convienient to put quick-access methods in a base class and sub-class all backing beans from it. This is similar to how Sun Creator's 1.0 manages backing beans and our methods are adopted from this. For severity our base class has two methods as below for INFO.
...
...
The first method enqueues a global message with INFO severity while the second method associates the INFO message with a component (most probably from a custom (page-specific) validation. We also have a base class for all our validators (which perform page-specific validation when necessary) which uses the following protected method for raising messages
...
Note that we only raise messages with WARN severity as our requirements preclude displaying anything which looks or smells like an error to our users.
As all our backing beans have these methods accesible to them, we can simply add appropriate calls to enqueue messages in our business logic such as
...
...
where the Messages class provides access to a messages properties file and performs standard parameter replacement using Apache's Common Lang StringUtils.
...
Rasing messages is one topic, displaying them another. As we need a consistent look and feel for all messages we choose to include a JSP in each page which handles all messages which are not component specific. Our PageMessages.jspf is as follows:
...
...
The messages are only displayed only if one or more messages are enqueued by conditionally rendering the table using rendered="#{! empty facesContext.maximumSeverity}"
which uses EL to check if the queues are empty or not. Depending on the level of severity we display an themed image followed by an optional pre-amble to the messages and then the global messages themselves. The global messages are displayed in table format.
You will notice that we use a backing bean (PageMessages.java) in request scope to control the JSPF. The code for this is as follows:
...
...
Our backing bean extends our basic UI base classes which provides access to central logging etc. You can see that if a component has enqueued a message of ERROR we add a localized message at the top of the page which (we hope) gracefully moderates the user-impact of seeing the same form again with a bunch of annotations!
The PageMessages.jspf is included into each JSP using the following code:
...
...