Section 5.7. Validation


5.7. Validation

Most software requires some kind of data entry, and in order to be user-friendly, an application should support the user as much as possible throughout the data entry process. This means identifying invalid input and giving the user a chance to fix it sooner rather than later.

JSF, as you might expect, has built-in support for validation . All JSF user interface components support validation through both built-in and custom validation rules.

Let's take a look at the Add Books form (Figure 5-4) in the JSF Library, which needs to enforce minimum field lengths and mandatory fields. The Add Books function is available to librarians who have logged into the system. It allows them to fill out a simple form to create a new book.

5.7.1. Adding Validators to Forms

Example 5-8 shows the JSP source for the Add Books form. We're using three different kinds of validation: required fields, built-in validators, and a custom validator (which we'll see in more detail in the next section). We're also using the <h:message> tag to display validation messages for each component.

Figure 5-4. Add Books form


Example 5-8. /view/addbook.jsp
 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>   <html>    <f:view>  <head>     <title>Add Book to Library</title>     <link rel="stylesheet" type="text/css"           href='<%= request.getContextPath(  ) + "/css/app.css" %>'>  </head>  <body>     <h1>Add Books to Library</h1>     <hr>    Enter information below to add a book to the library.  <h:form>     <table>     <tr>     <td>Title:</td>     <td><h:inputText  binding="#{addbookform.title}"            required="true">             <f:validateLength minimum="5"/>         </h:inputText>         <h:message style for="title"/>     </td>     </tr>     <tr>     <td>Author:</td>     <td><h:inputText  binding="#{addbookform.author}"            required="true"/>         <h:message style for="author"/>     </td>     </tr>     <tr>     <td>ISBN:</td>     <td><h:inputText  binding="#{addbookform.isbn}"            required="true">             <f:validator validatorId=              "com.oreilly.jent.jsf.library.validator.ISBNValidator"/>         </h:inputText>         <h:message style for="isbn"/>     </td>     </tr>     </table>       <p>     <h:commandButton value="Add Book" action="#{addbookform.addBook}"/>     <h:commandButton value="Verify" action="verify"/>     </p>   </h:form>   </body>   </f:view> </html>

Each time a JSF form is submitted, the engine runs through a Process Validations phase before any other actions take place. The validation process goes through each component and checks for associated validators. The condition associated with each validator is evaluated, and if the validator fails, a message is added to the page's message queue. Regardless of success or failure of any particular validator, every validator on the page is checked. If any validator fails, processing of the request is aborted and the user is returned to the original form, which can display the error messages produced by the validators and allow the user to try submitting again.

The <f:validateLength>, <f:validateDoubleRange>, and <f:validateLongRange> tags are all provided by the JSF implementation and allow validation of minimum lengths, floating-point double ranges, and long integer ranges, respectively. Each of these tags can be embedded within an input component to apply the specified validation behavior to that component. You can add multiple validators to a single component, and they will be processed in order.

Setting a field to required works a bit differently, as the various input components have a required attribute that can be set to true to make the fields mandatory (we do this for all three in Example 5-8). This check is also performed at the validation stage, and leaving out any required fields produces the same kind of message that any other validator would.

5.7.2. Displaying Validation Messages

The <h:message> and <h:messages> tags display the messages produced by the system during the validation phase. We saw the <h:messages> tag in Example 5-5; it's used to show all of the messages produced during page processing.

Messages, as we saw earlier, have two components: a high-level message and a detailed message. Messages are also associated with particular components: in this case, with the components that failed validation. This lets us display a validation error message alongside the component that the message is associated with. The <h:message> tag displays the detailed message associated with a particular component:

         <h:message style for="title"/>

The for attribute specifies the component ID for the component for which we want to display messages. Note that we have to specify component IDs manually rather than allowing the JSF engine to do it for us.

5.7.3. Custom Validators

The basic validators provided with the JSF API are useful but don't cover every possible situation. But not to fearyou can create your own validator classes by implementing the javax.faces.validator.Validator interface. We've built a simple one in Example 5-9 for validating ISBN numbers, using the simple ISBN checksum algorithm.[*] With this validator, we made a design decision not to throw an error if the ISBN is null; we leave that decision to the required attribute on the input field and display an error only if the input provided isn't a valid ISBN.

[*] The ISBN algorithm is simple. ISBNs may contain the digits 0-9 as well as the character X, which means 10. Multiply each digit by its distance from the righthand side of the ISBN code (10 for the first digit, 9 for the second digit, etc). Add the 10 products and divide by 11. If there is no remainder, the code is valid.

Example 5-9. ISBNValidator.java
 import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; import javax.faces.context.FacesContext; import javax.faces.component.UIComponent; import javax.faces.application.FacesMessage;   public class ISBNValidator implements Validator {       public void validate(FacesContext facesContext,                          UIComponent uiComponent, Object o)                          throws ValidatorException {           String val = o.toString(  );         if (val != null) {             if (val.length(  ) == 10) {               if(!checkISBN(val))                   throwValidatorException(                        "ISBN does not pass validation");             } else {                 throwValidatorException("ISBN must be 10 characters");             }         }     }       private boolean checkISBN(String ISBN) {         int sum = 0;         for (int i = 0; i < 10; i++) {             char current = ISBN.charAt(i);             int num = 0;             if (current == 'X')                 num = 10;             else                 num = current;             sum += (num * (10-i));         }         return (sum % 11 == 0);     }       private void throwValidatorException(String detail)             throws ValidatorException {         FacesMessage message = new FacesMessage(  );         message.setSeverity(FacesMessage.SEVERITY_ERROR);         message.setSummary("Invalid ISBN");         message.setDetail(detail);         throw new ValidatorException(message);     } }

In order to use this validator, we need to register it in the faces-config.xml file, associating a validator ID with the validator class. Here's how we do it for the library:

    <validator>         <validator-id>            ISBNValidator         </validator-id>         <validator-class>            com.oreilly.jent.jsf.library.validator.ISBNValidator         </validator-class>    </validator>

Once a custom validator is registered, we invoke it using the validator ID and the <f:validator> tag. Note that even through we've chosen to use the full package and class name as the validator ID (this is good practice in general, since it prevents confusion), we still have to register it before we can use it.

 <f:validator validator/>



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net