Search code examples
jsfseam2

Redirect from error page when there are no errors to display


I want my error page of my seam application to redirect to the home page if there is no error message to display (such as if the user bookmarks the error page).

I have a number of rules in pages.xml that direct to an error page like this:

<!-- pages.xml -->
  <exception class="org.jboss.seam.framework.EntityNotFoundException"
    log-level="warn">
    <redirect view-id="/error.xhtml">
      <message severity="warn">#{messages['jsf.RecordNotFound']}</message>
    </redirect>
  </exception>

After trying some unsuccessful EL expressions to try to check for no messages, I added a backing bean to do the check:

<!-- pages.xml -->
  <page view-id="/error.xhtml">
    <action execute="#{facesMessagesUtil.getGlobalMessagesCount()}" />
    <navigation>
      <rule if-outcome="none">
        <redirect view-id="/home.xhtml"/>
      </rule>
    </navigation>
  </page>

.

//FacesMessagesUtil.java

   import javax.faces.context.FacesContext;
   import org.jboss.seam.faces.FacesMessages;

   ...

   public String getGlobalMessagesCount()
   {
      log.info("currently {0} global facesMessages (seam)", FacesMessages.instance().getCurrentGlobalMessages().size());
      log.info("found messages in faces context: {0}", FacesContext.getCurrentInstance().getMessages().hasNext());
      log.info("got maximum severity: {0}", FacesContext.getCurrentInstance().getMaximumSeverity());

      if (!FacesContext.getCurrentInstance().getMessages().hasNext())
      {
         return "none";
      }
      return "some";
   }

The above method is invoked when I manually generate an error, but this redirects to home and shows the error message there. The log messages report that the classes I'm using don't seem to have any visibility of the message that is being displayed:

16:41:41,908 INFO  [FacesMessagesUtil] currently 0 global facesMessages (seam)
16:41:41,908 INFO  [FacesMessagesUtil] found messages in faces context: false
16:41:41,908 INFO  [FacesMessagesUtil] got maximum severity: null
  1. Is there a class in seam 2 that will allow me to check if there are any messages?
  2. Is there an EL expression that can do this check without an extra bean?

Solution

  • As best I can deduce with my investigations so far, the problem here is with how seam forwards FacesMessages from one JSF context to another. Essentially the messages appear to have been removed to some other seam component while pages.xml rules are being applied, then returned by the time the page is rendering. I have worked around this issue for now by showing a 'no errors' message (note that global messages are present during page render):

    <h:outputText id="noErrorsMessage"
        rendered="#{empty org.jboss.seam.international.statusMessages.currentGlobalMessages}">
        #{messages['jsf.NoErrors']}
    </h:outputText>
    

    and with some hard-coded redirect rules in one of my beans.