Harry Coder
Harry Coder

Reputation: 2740

How to set the exception message in a <h:message>?

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?

Upvotes: 0

Views: 2763

Answers (3)

Sebastian
Sebastian

Reputation: 19

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

Upvotes: 1

BalusC
BalusC

Reputation: 1108742

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.

Upvotes: 1

kosa
kosa

Reputation: 66637

 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.

Upvotes: 1

Related Questions