Thursday, February 2, 2012

PrimeFaces3 Tutorial : Form Validation Using BeanValidation API(JSR-303)

JSF2 has in-built support for form validations using Bean Validation API(JSR-303).
In my previous article PrimeFaces 3 Tutorial : Introduction & Form Validation , I have explained how to validate forms using JSF tags inside JSF xhtml pages.
Now Let us see how we can validate the forms using HibernateValidator which is reference implementation of JSR-303.

Note: Integrating JSR-303 with JSF2 doesn't have anything to do with PrimeFaces 3.
But I am planning to write a series of articles on PrimeFaces and JSR-303 integration is a part of it.
Please bear with me. :-)

Step#1: Add hibernate-validator dependency in pom.xml.

<dependency>
  <groupId>javax.validation</groupId>
  <artifactId>validation-api</artifactId>
  <version>1.0.0.GA</version>
  <scope>compile</scope>
 </dependency>

 <dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>4.0.0.GA</version>
  <scope>compile</scope>
 </dependency>

Here actually we don't need to specify validation-api.jar dependency explicitely. hibernate-validator.jar dependency will pull the validation-api.jar as its dependency.

Step#2:
Now let us specify the validation constraints for our Registration Form using Annotations on RegistrationForm.java bean.

package com.sivalabs.pfdemo.mb.ui;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class RegistrationForm
{
 
 private Integer userId;
 
 @NotEmpty(message="UserName is required")
 @Size(min=5, max=15, message="UsesrName should be of length from 5 to 15 chars")
 private String userName;
 
 @NotEmpty(message="Password is required")
 @Size(min=5, max=15, message="UsesrName should be of length from 5 to 15 chars")
 private String password;
 
 @NotEmpty(message="FirstName is required")
 @Size(min=5, max=15, message="UsesrName should be of length from 5 to 15 chars")
 private String firstName;
 
 private String lastName;
 
 @Pattern(regexp="[a-zA-Z0-9]+@[a-zA-Z]+.[a-zA-Z]{2,3}", message="Invalid EmailId")
 private String email;
 private String phone;
 private Date dob;
 private String gender;
 private List<String> interests = new ArrayList<String>();
 private boolean subscribeToNewsLetter;
  
 //setters/getters
 
}

Step#3:
Now you don't need to mention about validation constrains in JSF xhtml pages anymore. And you don't need to configure anything explicitly to tell JSF to validate RegistrationForm.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"> 

<h:head>

</h:head> 
<h:body> 
 <h2>Registration Form</h2>
 <h:form>
  <p:fieldset legend="Registration Form" widgetVar="regWidget" style="width: 600px;">
   <h:panelGrid columns="3" width="550" border="0">
    <h:outputLabel value="UserName" />
    <p:inputText value="#{registrationBean.registrationForm.userName}" id="userName"/>
    <p:message for="userName"/>
    
    
    <h:outputLabel value="Password" />
    <p:password value="#{registrationBean.registrationForm.password}" id="password"/>
    <p:message for="password" />
    
    <h:outputLabel value="FirstName" />
    <p:inputText value="#{registrationBean.registrationForm.firstName}" id="firstName"/>
    <p:message for="firstName" />
    
    
    <h:outputLabel value="LastName" />
    <p:inputText value="#{registrationBean.registrationForm.lastName}" id="lastName"/>
    <p:message for="lastName" />
    
    <h:outputLabel value="Email" />
    <p:inputText value="#{registrationBean.registrationForm.email}" id="email"/>
    <p:message for="email" />
    
    <h:outputLabel value="Phone" />
    <p:inputText value="#{registrationBean.registrationForm.phone}" id="phone"/>
    <p:message for="phone" />
    
    <h:outputLabel value="DOB" />
    <p:calendar value="#{registrationBean.registrationForm.dob}"
       id="dob"
       converterMessage="Invalid Date"
       pattern="dd-MM-yyyy">
     
    </p:calendar>
    <p:message for="dob" />
    
    <h:outputLabel value="Gender" />
    <h:selectOneRadio id="gender" 
          value="#{registrationBean.registrationForm.gender}" >
     <f:selectItems value="#{registrationBean.genders}" 
         var="gOp"
         itemLabel="#{gOp}"
         itemValue="#{gOp}"/>
    </h:selectOneRadio>
    <p:message for="gender" />
    
    
    <h:outputLabel value="Interests" />
    <p:selectManyCheckbox id="interests"
           value="#{registrationBean.registrationForm.interests}"
           layout="pageDirection">
     <f:selectItems value="#{registrationBean.interests}" var="intrOp"></f:selectItems>
    </p:selectManyCheckbox>
    <p:message for="interests" />
    
    <p:commandButton value="Register" action="#{registrationBean.register}" ajax="false"></p:commandButton>
   </h:panelGrid>
  </p:fieldset>
 
 </h:form>
</h:body> 
</html>

With these changes your Registration Form will be working same as using JSF validation tags.

References:
http://sivalabs.blogspot.in/2012/01/primefaces-3-tutorial-introduction-form.html
http://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html_single/

1 comment:

  1. Good.
    What is better? validations in the .java file (with annotations) or in the .xhtml file (with the primefaces tags)?

    ReplyDelete