Knowledge brings fear ... Prosthetic Conscious

Wednesday Jan 11, 2006

JSF allows one to add error, info, etc. messages during various phases of request processing by calling FacesContext.getCurrentInstance().addMessage(). It then allows these messages to be displayed in your presentation with the h:messages tag. Nice facility, as it allows messages to be associated with particular widgets on the page so one can say report a problem next to the widget where it occured. So far, so good.

The problem: if you are using request scoped beans, your messages don't display. They are lost. There is some discussion on the web about this being the correct behavior considering the JSF life cycle and request scoping. I don't buy that, because it works fine for session scoping and I find it hard to believe that the spec would allow the message facility to be broken for request scoped beans. I actually wonder if this is a bug on the JSF RI.  Maybe someone can explain the details. Suspiciously, all of the related JSF examples and tutorials out there use session scoped beans.

A clean way to get around this is to simply define a session scoped bean whose only purpose to add messages.

    <managed-bean>
        <managed-bean-name>messageHandler</managed-bean-name>
        <managed-bean-class>com.sun...MessageHandler</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

Define a bean called MessageHandler, and add a single method addMessage() that simply delegates to FacesContext.getCurrentInstance().addMessage().

public class MessageHandler {
    public void addMessage(String id, FacesMessage fm) {
        FacesContext.getCurrentInstance().addMessage(id, new FacesMessage(msg));
    }
}

Now add this bean as a managed property of your request scoped beans:

    <managed-bean>
        <managed-bean-name>aBean</managed-bean-name>
        <managed-bean-class>com.sun...ABean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>       
        <managed-property>
            <property-name>messageHandler</property-name>
            <value>#{messageHandler}</value>
        </managed-property>     
    </managed-bean>       

In your ABean implementation, add messages by calling getMessageHandler().addMessage(). This is clearly just a hack, but if you use request scoped beans and throwing JSF out the door isn't an option, you'll need it. I suppose the catch is if you're using request scoped beans, you may have a requirement to not be using them, in which cases this solution is invalid.
Comments:

Its good

Posted by 59.95.40.43 on August 24, 2007 at 09:41 PM PDT #

hi, I try to apply your idea in my code but the problem still persist, none message is displayed.

Sorry my poor english. ;-)

Posted by Antônio Junior on September 13, 2007 at 08:16 AM PDT #

Didn't work for too.
I'm still don't see the mesages... any clue ?

<managed-bean>
<managed-bean-name>messageHandler</managed-bean-name>
<managed-bean-class>com.iic.dcp.util.MessageHandler</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
<managed-bean-name>upload</managed-bean-name>
<managed-bean-class>com.iic.dcp.model.UploadData</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>messageHandler</property-name>
<value>#{messageHandler}</value>
</managed-property>
</managed-bean>

And maybe HERE can be the fault....
I added the property at UploadData class as follow.....

public class UploadData extends Form{
MessageHandler messageHandler;

public MessageHandler getMessageHandler() {
//AutoGenerated
return messageHandler;
}

public void setMessageHandler(MessageHandler messageHandler) {
//AutoGenerated
this.messageHandler = messageHandler;
} ........

And then
public List getData() {
this.getMessageHandler().addMessage(null, new FacesMessage("Checking.."));
}

so... what's wrong ?
Pls let me know.... tkx in advance!

Posted by skull on May 08, 2009 at 09:22 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed