0

I am trying to set an exception message in the <h:message>.

Here is the relevant view code:

<h:inputText id="titleId" value="#{bookController.book.title}"/>                        
<h:message for="titleId"/>
<h:commandButton value="Create a book" actionListener="#{bookController.doCreateBook}" action="listBooks"/>

I need a message to be displayed when the titleId is empty. My @Stateless EJB method throws an exception when the title is empty:

public Book createBook(Book book) throws CustomException {
    if(book.getTitle().isEmpty()) {
        throw new CustomException("Please, type a Title !");
    }   
    else {
        em.persist(book);
        return book;
    }       
}

My backing bean catches it and sets a message:

public void doCreateBook() {
    FacesContext ctx = FacesContext.getCurrentInstance();
    try {
        book = bookEJB.createBook(book);
        bookList = bookEJB.findBooks();
    } catch (CustomException e) {
        ctx.addMessage("titleId", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", e.getMessage()));
    }                               
}

What I except is, when the exception occurs, an error message must be displayed near the input text tag, but it isn't the case, the execution displays the page with list of books and the "Error" message displayed under the list, as shown below:

List of Books

How can I get the full exception message to show up next to the input field?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Harry Coder
  • 2,429
  • 2
  • 28
  • 32

3 Answers3

1
 ctx.addMessage("titleId", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", e.getMessage()));

Your message text is Error and you are getting same. Change "Error" here to what ever you want.

kosa
  • 65,990
  • 13
  • 130
  • 167
1

Apart from the erroneous message handling which Thinksteep has already answered, your other mistake is that you're doing validation in an action method. This is not right. You should be using JSF builtin validation facilities instead. Whenever the JSF builtin validation fails, then the action method will not be invoked and the page will also not navigate. The enduser sticks to the current form and the message will appear in the therefor specified <h:message> tag.

In your particular case, you just need to set the required attribute.

<h:inputText id="titleId" value="#{bookController.book.title}" required="true" />
<h:message for="titleId" />

If you want to customize the default required message, use requiredMessage attribute.

<h:inputText id="titleId" value="#{bookController.book.title}" 
    required="true" requiredMessage="Please, type a Title !" />
<h:message for="titleId" />

Remove that input validation from the EJB method. It doesn't belong there. The EJB isn't responsible for that, the caller (which is in your case thus your JSF code) is responsible for that.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you very much. So I have to consider it is not a good practice to manage business rules as input validations in the EJB ? – Harry Coder Jun 01 '12 at 09:04
  • You can **use** an EJB to perform validation, e.g. checking if an unique constraint isn't violated, but this should be done inside a `Validator` implementation which should throw a `ValidatorException` on failure. The EJB itself should just return true or false or something. See also e.g. http://stackoverflow.com/questions/6047866/jsf-2-0-how-to-write-validation/6047913#6047913 – BalusC Jun 01 '12 at 10:53
1

PUT <h:messages showDetail="true" />

Sebastian
  • 19
  • 1