Download
FAQ History |
![]() ![]() ![]() |
API
Search Feedback |
Performing Validation
JavaServer Faces technology provides a set of standard classes and associated tags that page authors and application developers can use to validate a component's data. Table 21-15 lists all of the standard validator classes and the tags that allow you to use the validators from the page.
All of these validator classes implement the
Validator
interface. Component writers and application developers can also implement this interface to define their own set of constraints for a component's value.This section shows you how to use the standard
Validator
implementations, how to write your own custom validator by implementing theValidator
interface, and how to display error messages resulting from validation failures.Displaying Validation Error Messages
A page author can output error messages resulting from both standard and custom validation failures using the
output_errors
tag. Here is an example of anoutput_errors
tag:The
output_errors
tag causes validation error messages to be displayed wherever the tag is located on the page. Thefor
attribute of the tag must match the id of the component whose data requires validation checking. This means that you must provide an ID for the component by specifying a value for the component tag'sid
attribute. If thefor
attribute is not specified, the errors resulting from all failed validations on the page will display wherever the tag is located on the page. The next two sections show examples of using theoutput_errors
tag with the validation tags.Using the Standard Validators
When using the standard
Validator
implementations, you don't need to write any code to perform validation. You simply nest the standard validator tag of your choice inside a tag that represents a component of type UIInput (or a subclass ofUIInput
) and provide the necessary constraints, if the tag requires it. Validation can only be performed on components whose classes extendUIInput
since these components accept values that can be validated.The
Customer.jsp
page of thecardemo
application uses two of the standard validators:StringRangeValidator
andRequiredValidator
. This section explains how to use these validators. The other standard validators are used in a similar way.Using the Required Validator
The
zip
input_text
tag onCustomer.jsp
uses aRequiredValidator
, which checks if the value of the component is null or is an empty String. If your component must have a non-null
value or aString
value at least one character in length, you should register this validator on the component. If you don't register aRequiredValidator
, any other validators you have registered on the component will not be executed. This is because the other validators can only validate a non-null
value or aString
value of at least one character. Here is thezip
input_text
tag fromCustomer.jsp
:<h:input_text id="zip" valueRef="CustomerBean.zip" size="10"> <f:validate_required /><cd:format_validator formatPatterns=
"99999|99999-9999|### ###
"/>
</h:input_text><h:output_errors for=
"zip
"/>
The
zip
component tag contains a custom validator tag besides thevalidate_required
tag. This custom validator is discussed in section Creating a Custom Validator. In order for other validators to be processed, thevalidate_required
tag is needed to first check if the value is null or a String value of at least one character. However, you can register the validator tags in any order; you don't have to register the RequiredValidator first.Because of the
output_errors
tag, an error will display on the page if the value is null or an emptyString
. When the user enters a value in response to seeing the error message, the other validators can check the validity of the value.Using the StringRangeValidator
The
middleInitial
component on theCustomer.jsp
page uses aStringRangeValidator
, which checks if the user only enters an alphabetic character in themiddleInitial
component. Here is themiddleInitial
input_text
tag fromCustomer.jsp
:<h:input_text id="middleInitial" size="1" maxlength="1" valueRef=
"CustomerBean.middleInitial
"> <f:validate_stringrange minimum="A" maximum="z"/> </h:input_text> <h:output_errors clientId="middleInitial"/>
The
middleInitial
tag uses thesize
attribute and themaxlength
attribute. These attributes restrict the input to one character.The
validate_stringrange
tag uses aStringRangeValidator
whose attributes restrict the value entered to a single alphabetic character from the range A to Z, ignoring case.Creating a Custom Validator
If the standard validators don't perform the validation checking you need, you can easily create a custom validator for this purpose. To create and use a custom validator, you need to:
The
cardemo
application uses a general-purpose custom validator that validates input data against a format pattern that is specified in the custom validator tag. This validator is used with the Credit Card Number field and the Zip code field. Here is the custom validator tag used with the Zip code field:According to this validator, the data entered in the Zip code field must be either:
The rest of this section describe how this validator is implemented, how it works, and how to use it in a page.
Implement the Validator Interface
All custom validators must implement the
Validator
interface. This implementation must contain a constructor, a set of accessor methods for any attributes on the tag, and avalidate
method, which overrides thevalidate
method of theValidator
interface.The
FormatValidator
class implementsValidator
and validates the data on the Credit Card Number field and the Zip code field. This class defines accessor methods for setting the attributeformatPatterns
, which specifies the acceptable format patterns for input into the fields.In addition to the constructor and the accessor methods, the class overrides
Validator.validate
and provides a method calledgetMessageResources
, which gets the custom error messages to be displayed when theString
is invalid.All custom
Validator
implementations must override thevalidate
method, which takes theFacesContext
and the component whose data needs to be validated. This method performs the actual validation of the data. Here is thevalidate
method fromFormatValidator
:public void validate(FacesContext context, UIComponent component) { if ((context == null) || (component == null)) { throw new NullPointerException(); } if (!(component instanceof UIOutput)) { return; } if ( formatPatternsList == null ) { component.setValid(true); return; } String value = (((UIOutput)component).getValue()).toString(); Iterator patternIt = formatPatternsList.iterator(); while (patternIt.hasNext()) { valid = isFormatValid(((String)patternIt.next()), value); if (valid) { break; } } if ( valid ) { component.setValid(true); } else { component.setValid(false); Message errMsg = getMessageResources().getMessage(context, FORMAT_INVALID_MESSAGE_ID, (new Object[] {formatPatterns})); context.addMessage(component, errMsg); } }This method gets the local value of the component and converts it to a
String
. It then iterates over theformatPatternsList
list, which is the list of acceptable patterns as specified in theformatPatterns
attribute of theformat_validator
tag. While iterating over the list, this method checks the pattern of the local value against the patterns in the list. If the value's pattern matches one of the acceptable patterns, this method stops iterating over the list and marks the components value as valid by calling the component'ssetValid
method with the valuetrue
. If the pattern of the local value does not match any pattern in the list, this method: marks the component's local value invalid by callingcomponent.setValid(false)
, generates an error message, and queues the error message to theFacesContext
so that the message is displayed on the page during the Render Response phase.The
FormatValidator
class also provides thegetMessageResources
method, which returns the error message to display when the data is invalid:public synchronized MessageResources getMessageResources() { MessageResources carResources = null; ApplicationFactory aFactory = (ApplicationFactory) FactoryFinder.getFactory( FactoryFinder.APPLICATION_FACTORY); Application application = aFactory.getApplication(); carResources = application.getMessageResources("carDemoResources"); return (carResources); }This method first gets an
ApplicationFactory
, which returnsApplication
instances. The Application instance supports thegetMessageResources(String)
method, which returns theMessageResources
instance identified bycarResources
. ThisMessageResources
instance is registered in the application configuration file. This is explained in the next section.Register the Error Messages
If you create custom error messages, you need to make them available at application startup time. You do this by registering them using the application configuration file.
Note: This technique for registering messages is not utilized in the version of cardemo shipped with this release. The cardemo application will be updated to use this technique in future releases.
Here is the part of the file that registers the error messages:
<message-resources> <message-resources-id> carDemoResources </message-resources-id> <message> <message-id>cardemo.Format_Invalid</message-id> <summary xml:lang="en"> Input must match one of the following patterns {0} </summary> <summary xml:lang="de"> Eingang mu? eins der folgenden Muster zusammenbringen {0} </summary> <summary xml:lang="es"> La entrada debe emparejar uno de los patrones siguientes {0} </summary> <summary lang="fr"> L'entrée doit assortir un des modèles suivants {0} </summary> </message> </message-resources>The
message-resources
element represents a set of localizable messages, which are all related to a uniquemessage-resources-id
. Thismessage-resources-id
is the identifier under which theMessageResources
class must be registered. It corresponds to a static message ID in theFormatValidator
class:The
message
element can contain any number of summary elements, each of which defines the localized messages. Thelang
attribute specifies the language code.This is all it takes to register message resources. Prior to this release, you had to write an implementation of the
MessageResources
class, create separate XML files for each locale, and add code to aServletContextListener
implementation. Now, all you need are a few simple lines in the application configuration file to register message resources.Register the Custom Validator
Just as the message resources need to be made available at application startup time, so does the custom validator. You register the custom validator in the application configuration file with the
validator
XML tag:<validator> <description>FormatValidator Description</description> <validator-id>FormatValidator</validator-id> <validator-class>cardemo.FormatValidator</validator-class> <attribute> <description> List of format patterns separated by '|' </description> <attribute-name>formatPatterns</attribute-name> <attribute-class>java.lang.String</attribute-class> </attribute> </validator>The
validator-id
andvalidator-class
are required subelements. Thevalidator-id
represents the identifier under which theValidator
class should be registered. This ID is used by the tag class corresponding to the customvalidator
tag.The
validator-class
element represents the fully-qualified class name of theValidator
class.The
attribute
element identifies an attribute associated with theValidator
. It has requiredattribute-name
andattribute-class
subelements. Theattribute-name
element refers to the name of the attribute as it appears in thevalidator
tag. Theattribute-class
element identifies the Java type of the value associated with the attribute.Create a Custom Tag or Use the validator Tag
There are two ways to register a
Validator
instance on a component from the page:If you want to configure the attributes in the
Validator
implementation rather than from the page, the page author only needs to nest af:validator
tag inside the tag of the component whose data needs to be validated and set thevalidator
tag'stype
attribute to the name of theValidator
implementation:<h:input_text id="zip" valueRef="CustomerBean.zip" size="10" ... > <f:validator type="cardemo.FormatValidator" /> ... </h:input_text>If you want to use a custom tag, you need to:
Writing the Tag Handler
The tag handler associated with a custom validator tag must extend the
ValidatorTag
class. This class is the base class for all custom tag handlers that createValidator
instances and register them on a UI component. TheFormatValidatorTag
is the class that registers theFomatValidator
instance.The
FormatValidator
tag handler class:
- Sets the ID of the
Validator
by callingsuper.setId("FormatValidator")
.- Provides a set of accessor methods for each attribute defined on the tag.
- Implements the
createValidator
method of theValidatorTag
class. This method creates an instance of theValidator
and sets the range of values accepted by the validator.Here is the
createValidator
method fromFormatValidator
:protected Validator createValidator() throws JspException { FormatValidator result = null; result = (FormatValidator) super.createValidator(); Assert.assert_it(null != result); result.setFormatPatterns(formatPatterns); return result; }This method first calls
super.createValidator
to get a newValidator
and casts it toFormatValidator
.Next, the tag handler sets the
Validator
instance's attribute values to those supplied as tag attributes in the page. The handler gets the attribute values from the page via the accessor methods that correspond to the attributes.Writing the Tag Library Descriptor
To define a tag, you need to declare it in a tag library descriptor (TLD), which is an XML document that describes a tag library. A TLD contains information about a library and each tag contained in the library.
The custom validator tag for the Credit Card Number and Zip Code fields is defined in the
cardemo.tld
, located in<
JWSDP_HOME
/jsf/samples/cardemo/web/WEB-INF
directory of your download bundle. It contains only one tag definition, forformat_validator
:<tag> <name>format_validator</name> <tag-class>cardemo.FormatValidatorTag</tag-class> <attribute> <name>formatPatterns</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag>The
name
element defines the name of the tag as it must be used in the page. Thetag-class
element defines the tag handler class. The attribute elements define each of the tag's attributes. For more information on defining tags in a TLD, please see Tag Library Descriptors (page 737).Adding the Custom Tag to the Page
To use the custom validator in the JSP page, you need to declare the custom tag library that defines the custom tag corresponding to the custom component.
To declare the custom tag library, include a
taglib
directive at the top of each page that will contain the custom validator tags included in the tag library. Here is thetaglib
directive that declares the cardemo tag library:The
uri
attribute value uniquely identifies the tag library. Theprefix
attribute value is used to distinguish tags belonging to the tag library. Here is theformat_validator
tag from thezip
tag onCustomer.jsp
:To register this validator on the
zip
component (corresponding to the Zip Codefield) you need to nest theformat_validator
tag within thezip
component tag:<h:input_text id="zip" valueRef="CustomerBean.zip" size="10" > ... <cd:format_validator formatPatterns="99999|99999-9999|### ###" /> </h:input_text> <h:output_errors for="zip" />The
output_errors
tag following thezip
input_text
tag will cause the error messages to display next to the component on the page. Thefor
attribute refers to the component whose value is being validated.A page author can use the same custom validator for any similar component by simply nesting the custom validator tag within the component tag.
Download
FAQ History |
![]() ![]() ![]() |
API
Search Feedback |
All of the material in The Java(TM) Web Services Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.