The JSF Life Cycle

Conversion

Validation

A converter for an input text field requiring a payment amount using a format having two digits after the decimal point:
   <h:inputText value="#{payment.amount}">
      <f:convertNumber minFractionDigits="2"/>
   </h:inputText>
	
A converter for an output text field that supplies a currency symbol and decimal separators:
   <h:outputText value="#{payment.amount}">
      <f:convertNumber type="currency"/>
   </h:outputText>

	
A converter for an input text field requiring a date string using a given date format:
   <h:inputText value="#{payment.date}">
      <f:convertDateTime pattern="MM/yyyy"/>
   </h:inputText>
	
Built-in JSF converters have names of the form javax.faces.converter.<TYPE> where <TYPE> is one of: Besides using an f:convert<TYPE> tag, you can use the converter attribute with a JSF HTML tag.

For example, the following are equivalent:

   <h:outputText value="#{payment.date}" converter="javax.faces.converter.DateTime"/>

   <h:outputText value="#{payment.date}">
      <f:convertDateTime/>
   </h:outputText>
	
When a conversion error occurs: The error message must be explicitly included in the page or it will not appear on page redisplay.

Displaying error messages (h:message and h:messages) is covered in Ch.4: Standard JSF Tags.

If you don't like the default error message provided by a standard converter, you can provide a custom converter error message for a component.

Set the converterMessage attribute of the component whose value is being converted. For example:

   <h:inputText ... converterMessage="Not a valid number."/>
	
Key role of validation: protect the model from getting into an inconsistent state.

Built-in validation mechanisms:

Currently JSF does not explicitly support client-side validation; all validation occurs on the server side after the user submits form data.
Suppose a credit card number field requires at least 13 characters:
   <h:inputText id="card" value="#{payment.card}">
      <f:validateLength minimum="13"/>
   </h:inputText>
	
To specify that an input is required:
   <h:inputText id="date" value="#{payment.date}">
      <f:validateRequired/>
   </h:inputText>
	
Or, use the required attribute that is supported by all input tags:
   <h:inputText id="date" value="#{payment.date}" required="true"/>
	
Numerical input values may be required to be in a given range. Here is a validator that checks that the supplied value is ≥ 10 and ≤ 10000:
   <h:inputText id="amount" value="#{payment.amount}">
      <f:validateLongRange minimum="10" maximum="10000"/>
   </h:inputText>
	

Validation errors are handled in the same way as conversion errors.

You can supply a custom message for a component by setting the requiredMessage or validatorMessage attribute, like this:

   <h:inputText id="card" value="#{payment.card}" required="true"
                requiredMessage="#{msgs.cardRequired}"
                validatorMessage="#{msgs.cardInvalid}">
      <f:validateLength minimum="13"/>
   </h:inputText>
       
Validation errors (and conversion errors) force a redisplay of the current page, which can sometimes be problematic.

Suppose a Cancel button is on a page with required fields.

If the user clicks Cancel, leaving a required field blank, then the validation mechanism forces the current page to be redisplayed.

Use the immediate attribute to bypass validation, forcing the command to be executed during the Apply Request Values phase:

   <h:commandButton value="Cancel" action="cancel" immediate="true"/>
	
JSF allows input validation through the annotation of bean properties, like this:
   public class PaymentBean {
      @Size(min=13) private String card;
      @Future public Date getDate() { ... }
      ...
   }
	
Advantages of doing this over page-level validation:
Standard converters deal with numbers and dates.

If an application needs to convert string inputs to other types, it must implement an application-specific converter class.

The Converter interface (package javax.faces.converter):

   Object getAsObject(FacesContext context, UIComponent component, String newValue)
	
converts a string into an object of the desired type.

If the conversion cannot be carried out, create a FacesMessage that describes the error and throw a ConverterException

   String getAsString(FacesContext context, UIComponent component, Object value)
	
converts an object into a string representation to be displayed in the client interface.
A custom validator must implement the Validator interface (package javax.faces.validator) that has one method:
   void validate(FacesContext context, UIComponent component, Object value)
	
If validation fails, generate a FacesMessage and throw a ValidatorException.
Custom converter and validator classes just described have a shortcoming — they do not allow attributes to be specified in the web pages that use them.

Examples where attributes would be useful:

The example in this section implements custom tags that allow this:
   <h:outputText value="#{payment.card}">
      <corejsf:convertCreditcard separator="-"/>
   </h:outputText>

   <h:inputText id="card" value="#{payment.card}" required="true">
      <corejsf:validateCreditCard errorDetail="#{msgs.creditCardError}"/>
   </h:inputText>
	
This section collects the example web applications used in this chapter.