Reputation: 570
I have a small webapplication for a library, with a customized ISBN validator. My .xhtml page for adding a book looks like this:
<fieldset>
<h:messages/>
<ul>
<li>
<h:outputLabel for="isbn" value="#{labels.isbn}:" />
<h:inputText id="isbn" value="#{addController.book.isbn.isbnValue}" required="true" requiredMessage="- ISBN must be filled in.">
<f:validator validatorId="isbnValidator" />
</h:inputText>
</li>
<li>
<h:outputLabel for="title" value="#{labels.title}:" />
<h:inputText id="title" value="#{addController.book.title}" required="true" requiredMessage="- Title must be filled in."/>
</li>
<li>
<h:outputLabel for="name" value="#{labels.name}:" />
<h:inputText id="name" value="#{addController.book.person.name}" required="true" requiredMessage="- Name must be filled in."/>
</li>
<li>
<h:outputLabel for="firstname" value="#{labels.firstname}:" />
<h:inputText id="firstname" value="#{addController.book.person.firstname}" />
</li>
</ul>
<h:commandButton id="addButton" action="#{addController.save}" value="#{labels.add}" />
<h:commandButton id="cancelButton" action="bookOverview" value="#{labels.cancel}" />
</fieldset>
</ui:define>
The isbnValidator
of the first input field is this class:
private Isbn isbn;
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
isbn = new Isbn((String) value);
if (!isbn.isIsbn17Characters()) {
addMessageToContext(context, "- ISBN needs to have 17 characters");
}
if (isbn.isIsbn17Characters() && !isbn.isIsbnInRightFormat()) {
addMessageToContext(context, "- Wrong format, it should be like 'XXX-XX-XXX-XXXX-X'");
}
if (isbn.isIsbn17Characters() && isbn.isIsbnInRightFormat() && !isbn.isIsbnFormatValid()) {
addMessageToContext(context, "- ISBN can only contain numbers, and no other tokens");
}
if (isbn.isIsbn17Characters() && isbn.isIsbnInRightFormat() && isbn.isIsbnFormatValid()
&& !isbn.isLastNumberValid()) {
addMessageToContext(context, "- Last number of the ISBN should be " + isbn.getCorrectLastNumber()
+ " with those 12 numbers");
}
}
public static void addMessageToContext(FacesContext context, String message) {
FacesMessage facesMessage = new FacesMessage();
facesMessage.setSummary(message);
facesMessage.setDetail(message);
context.addMessage("isbn", facesMessage);
}
When I click the 'add' button, the book should be added to the database.
When the ISBNfield, namefield or titlefield aren't filled in, I get the corresponding error message. But when my fields are filled in, and the ISBN validation fails, he shows the error message, but he still adds the book (with a wrong ISBN-number) to the database.
A solution which I thought about: If my messages tags is not empty, he shouldn't add the book to the database. But how can I check that?
Or is there a better solution to my problem?
Upvotes: 2
Views: 464
Reputation: 1109715
The validation error message handling is wrong. You need to throw a ValidatorException
with a FacesMessage
instead of adding the FacesMessage
manually.
So instead of all those
addMessageToContext(context, "- ISBN needs to have 17 characters");
you need to do
throw new ValidatorException(new FacesMessage("- ISBN needs to have 17 characters"));
This is for JSF sign that the input is invalid and hence the action method won't be invoked. You also don't need to specify the client ID, it will just end up in the <h:message>
associated with the input component where this validator is fired on.
Upvotes: 3