[wp_ad_camp_5]
This post demonstrates how to create custom validation methods in the same @ManagedBean
class and use them accordingly.
Requirements
Stuff used in this post.
- JSF 2.2
- javax.faces-2.2.8.jar
- JDK 8
Custom Validation Methods
These are the custom validation methods and their purposes are as follow for our example:
validateProductCode
- A valid product code is required must start with
001-
- A valid product code is required must start with
validateProductName
- A valid product name is required and must not exceed 100 characters.
These methods declare a particular set of parameters in a specific order so that they can be invoked by the JSF
framework correctly.
[wp_ad_camp_4]
Validation Method Parameters
A custom validation method can have any method name as long it follows these rules.
- The method must be
public
andnon-static
- The method returns
void
- The method has 3 parameters in a particular order declared in its method signature
public void validationAnyNameMethod(FacesContext context,
UIComponent component, Object value)
- The method must declare that it throws
ValidatorException
(or not)
For instance,
1 2 3 4 5 | public void validateField01(FacesContext context, UIComponent component, Object value) throws ValidatorException { ... } |
Sample Codes
Managed bean – ProductWithCustomValidationForm
[wp_ad_camp_3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package com.turreta.jsf.bean; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.ValidatorException; @ManagedBean public class ProductWithCustomValidationForm { // Valid product codes start with "001-" private String productCode; private String productName; public ProductWithCustomValidationForm() { } public String getProductCode() { return productCode; } public void setProductCode(String productCode) { this.productCode = productCode; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } /** * Custom validation methods */ public void validateProductCode(FacesContext context, UIComponent component, Object value) throws ValidatorException { if(!value.toString().startsWith("001-")) { throw new ValidatorException(new FacesMessage("Invalid Product code. It must start with 001-")); } } public void validateProductName(FacesContext context, UIComponent component, Object value) throws ValidatorException { if(value.toString().length() > 100) { throw new ValidatorException(new FacesMessage("Product Name is too long. Max length allowed = 100")); } } } |
New Product Page – Request
This is our input page where users enter and save information for new 001-
products.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>New Product</title> <style> .form-error {color:red} </style> </h:head> <h:body> <h:form> <!-- Commented out to use individual h:message instead <h:messages styleClass="form-error"/> --> <table> <tr> <td>Product Code:</td> <td> <h:inputText id="field1" value="#{productWithCustomValidationForm.productCode}" label="Product Code" required="true" validator="#{productWithCustomValidationForm.validateProductCode}" /> <h:message for="field1" styleClass="form-error"/> </td> </tr> <tr> <td>Product Name:</td> <td> <h:inputText id="field2" value="#{productWithCustomValidationForm.productName}" required="true" label="Product Name" validator="#{productWithCustomValidationForm.validateProductName}"/> <h:message for="field2" styleClass="form-error"/> </td> </tr> </table> <h:commandButton value="Submit" action="new_product_response"/> </h:form> </h:body> </html> |
Second Page – Response
This page displays the newly added product details.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> <h:head> <title>New Product - Response</title> </h:head> <h:body> New Product saved! <table> <tr> <td><b>Product code:</b></td> <td>#{productWithCustomValidationForm.productCode}</td> </tr> <tr> <td><b>Product Name:</b></td> <td>#{productWithCustomValidationForm.productName}</td> </tr> </table> </h:body> </html> |
Testing
With Validation Errors
Here we provided a product code
that does not start with 001-
and a product name
that is too long.
Request Page
[wp_ad_camp_2]
Response
Without Validation Errors
This time we provided a product code
that starts with 001-
and a product name
with valid number of characters.
Request Page
Response
Using JSF Validator Interface instead
Each of these validation method can be converted into a class that implements the javax.faces.validator.Validator
interface.
The reason why our validation methods have a specific set of parameters in a specific order is because JSF
invokes them knowing that these methods are implementations of abstract method in javax.faces.validator.Validator
.
We’ll cover that interface in part two of this post.
References
[wp_ad_camp_1]
- http://docs.oracle.com/javaee/7/api/javax/faces/validator/Validator.html
- http://grepcode.com/file/repo1.maven.org/maven2/com.sun.faces/jsf-api/2.2.8/javax/faces/validator/Validator.java