JSF Validation - Part 3
>> 19 May 2010
In this part we will see how to customize validation for your need.
If validation is not supported by the standard validators
In this case you can :
- Write a method in your bean (JSF mainly works with beans to get and set Data)
- Write a custom validator
- Create your own library and tags
Write a custom method
You can provide a method in your business bean. The validator attribute will use this method to validate the input. If the converted value is considered invalid, it should throw a ValidatorException and provide a FacesMessage.
The Expression Language is used here to point to a method on an arbitrary JavaBean that adheres to the contract and signature of Validator.validate( ). This can greatly simplify application design by allowing you to put the
business logic, and the method to validate it, in the same class.
Note:
Detailed message is used with <h:message />.By default, the UI Messages will
display the summary messages.(<h:messages /> with "s")
Note:
validate must be defined like this :
public void validate(FacesContext context,
UIComponent component,
Object enterdValue)
throws ValidatorException
In a bean add a method (here ValidateMail)
//==================================================
//validateMail
//==================================================
public void validateMail(FacesContext context,//jsf engine)
UIComponent component, //the component
Object enteredValue//must not be empty
)throws ValidatorException
{
String email=(String)enteredValue;
if(email.trim().equals("") || !email.matches("^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\\-+)|([A-Za-z0-9]+\\.+)|([A-Za-z0-9]+\\++))*[A-Za-z0-9]+@((\\w+\\-+)|(\\w+\\.))*\\w{1,63}\\.[a-zA-Z]{2,6}$") )
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Error Entered e-mail",//summary msg
"Entered e-mail: \""+email+"\" is invalid"//detailed msg
));
}
In testValidation.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test Validation</title>
</head>
<body>
<h:messages/>
<f:view>
<h:form id="form">
<h:outputLabel for="name" value="Enter Name"/>
<h:inputText required="true" label="name" id="sname">
<f:validateLength minimum="3" maximum="20"/>
</h:inputText>
<h:outputLabel for="double" value="Enter Double Value"/>
<h:inputText required="true" label="double">
<f:validateDoubleRange minimum="2.0" maximum="20.1" />
</h:inputText>
<h:outputLabel for="long" value="Enter Long Value"/>
<h:inputText required="true" label="long">
<f:validateLongRange minimum="0" maximum="10" />
</h:inputText>
<h:outputLabel for="email" value="Enter Your email"/>
<h:inputText required="true" label="email" validator="#{person.validateMail}"/>
<h:commandButton action="ok" value="Validate" />
</h:form>
</f:view>
</body>
</html>
Display
If one of the conditions is missed, an error message is displayed
When email is valid no more error message
Create a Validator
1.Create a class that implements the javax.faces.validator.Validator interface
2.Implement the validate() method
3.Register this validator in the configuration file "faces-confix.xml"
4.Put <f:validator validatorId="xxx" to use it.
Note:
Using a custom validator offers the possibility of re-using this component.
Create a class that implements the javax.faces.validator.Validator interface
EMailValidator.java
package fr.iipt.ka.faces;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class EMailValidator implements Validator{
//==================================================
//validateMail
//==================================================
public void validate(FacesContext context,//jsf engine)
UIComponent component, //the component
Object enteredValue//must not be empty
)throws ValidatorException
{
String email=(String)enteredValue;
if(email.trim().equals("") || !email.matches("^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\\-+)|([A-Za-z0-9]+\\.+)|([A-Za-z0-9]+\\++))*[A-Za-z0-9]+@((\\w+\\-+)|(\\w+\\.))*\\w{1,63}\\.[a-zA-Z]{2,6}$") )
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Error Entered e-mail - custom class",//summary msg
"Entered e-mail: \""+email+"\" is invalid"//detailed msg
));
}
}
Edit faces-config.xml
<faces-config>
...
<validator>
<validator-id>checkMail</validator-id>
<validator-class>fr.iipt.ka.faces.EMailValidator</validator-class>
</validator>
</faces-config>
In testValidation.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test Validation</title>
</head>
<body>
<h:messages/>
<f:view>
<h:form id="form">
<b>Validate email using custom method in JavaBean</b><br/>
<h:outputLabel for="email" value="Enter Your email"/><br/>
<h:inputText required="true" label="email" validator="#{person.validateMail}"/><br/>
<b>Validate email using custom custom class</b><br/>
<h:outputLabel for="email" value="Enter Your email"/><br/>
<h:inputText required="true" label="email2">
<f:validator validatorId="checkMail"/>
</h:inputText>
<h:commandButton action="ok" value="Validate" />
</h:form>
</f:view>
</body>
</html>
Display
Create your own tags
It's possible to create custom validation classes and put them in a facelet tag lib, use them the same way as the core tag lib or html tag lib. Steps to do this are the same as creating a custom validation class with one exception, you must create a taglib descriptor.
First step :
Create a custom validation class this class must implement Validator and provide validate method (the same as the previous custom validation class). Let it have a modified error message (just to see the result)
EMailValidator2.java
package fr.iipt.ka.faces;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class EMailValidator2 implements Validator{
//==================================================
//validateMail
//==================================================
public void validate(FacesContext context,//jsf engine)
UIComponent component, //the component
Object enteredValue//must not be empty
)throws ValidatorException
{
String email=(String)enteredValue;
if(email.trim().equals("") || !email.matches("^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\\-+)|([A-Za-z0-9]+\\.+)|([A-Za-z0-9]+\\++))*[A-Za-z0-9]+@((\\w+\\-+)|(\\w+\\.))*\\w{1,63}\\.[a-zA-Z]{2,6}$") )
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Error Entered e-mail - facelet tag lib",//summary msg
"Entered e-mail: \""+email+"\" is invalid"//detailed msg
));
}
}
Second Step
Register this class as validator in the configuration file "faces-confix.xml", give your validator any ID and specify it's class.
<faces-config>
...
...
<validator>
<validator-id>ka.faceletTag.1</validator-id>
<validator-class>fr.iipt.ka.faces.EMailValidator2</validator-class>
</validator>
</faces-config>
Third Step
Create a facelet tag lib descriptor (in src/META-INF folder), give it a name with .taglib.xml extension. Define your tag(s), (every tag will be called in facelet .xhtml file with it's name). Associate the tag name with it's validator.
ka.taglib.xml
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib xmlns="http://java.sun.com/JSF/Facelet" >
<namespace>http://iipt.fr</namespace>
<tag>
<tag-name>validateMail</tag-name>
<validator>
<validator-id>ka.faceletTag.1</validator-id>
</validator>
</tag>
</facelet-taglib>
Now you can use your tag(s)
testValidation.xhtml
Declare a name space with a prefix, in the body of <h:inputText use the same prefix with your custom tag name
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ka="http://iipt.fr"
>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test Validation</title>
</head>
<body>
<h:messages/>
<f:view>
<h:form id="form">
<b>Validate email using custom method in JavaBean</b><br/>
<h:outputLabel for="email" value="Enter Your email"/><br/>
<h:inputText required="true" label="email" validator="#{person.validateMail}"/><br/>
<b>Validate email using custom class</b><br/>
<h:outputLabel for="email" value="Enter Your email"/><br/>
<h:inputText required="true" label="email2">
<f:validator validatorId="checkMail"/>
</h:inputText>
<br/>
<b>Validate email using facelet tag lib</b><br/>
<h:outputLabel for="email" value="Enter Your email"/><br/>
<h:inputText required="true" label="email3">
<ka:validateMail />
</h:inputText>
<br/>
<h:commandButton action="ok" value="Validate" />
</h:form>
</f:view>
</body>
</html>
Display
0 comments:
Post a Comment