3
votes

In my jsf application I have a button for sending mail. And each time it clicked I want to show message that mail was or wasn't sent.

This is a typical request-scope functionality. But the problem is that I have 1 backing bean with session scope now. And all data is in this bean. And method 'send' referred by action attribute of the button is in this bean.

So, what is the way out? If I should create one more request-scope bean then how should I refer to it from my session bean?

2
Request scoped data belongs in the request scope. Session scoped data belongs in the session scope. It can't be that more clear/obvious. In other words: refactor. - BalusC
I need to send by mail data from session scope (I can't put them to the request scope). But the result message should be in request scope (because I want to see it only one time just after sending mail). What can I refactor? - Roman
I realize, if it's only the messaging, then you can also just grab FacesMessage. See my answer. - BalusC

2 Answers

3
votes

Another approach, you can make use of FacesMessage here which you add to the context using FacesContext#addMessage(). FacesMessages are request based and likely more suited for the particular functional requirement than some custom messaging approach.

Here's an example of the bean action method:

public void sendMail() {
    FacesMessage message;
    try {
        Mailer.send(from, to, subject, message);
        message = new FacesMessage("Mail successfully sent!");
    } catch (MailException e) {
        message = new FacesMessage("Sending mail failed!");
        logger.error("Sending mail failed!", e); // Yes, you need to know about it as well! ;)
    }
    FacesContext.getCurrentInstance().addMessage(null, message);
}

With a null clientId the message becomes "global", so that you can make use of the following construct to display only global messages:

 <h:messages globalOnly="true" />

Update: to have the success and error message displayed in a different style, play with the FacesMessage.Severity:

        message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Mail successfully sent!", null);
    } catch (MailException e) {
        message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sending mail failed!", null);

.. in combination with infoClass/infoStyle and errorClass/errorStyle in h:messages:

 <h:messages globalOnly="true" infoStyle="color:green" errorStyle="color:red" />
1
votes

Either:

  • just push the message onto the request scope from the send method (via the ExternalContext)
  • refactor the method to a request-scope bean and inject any session information it needs (the managed bean framework can do this)