The ICEfaces Tutorial
Table of Contents


Lesson: Using JSF converters with ICEfaces components

How to use JSF Converters with ICEfaces Components

Why is conversion important? Conversion is the process of ensuring data is of the right object or type. This can be very helpful by eliminating erroneous information from getting into your system. In the JSF lifecycle, conversion occurs in the apply request values phase. This is before component data is bound to your backing bean model. By having it occur in the apply request values phase you can make certain assumptions that the data being sent into the backing bean will be of the correct type. This helps you to focus on business login rather than qualifications of input data.

For this tutorial we will be using a simple JSF application to demonstrate how to use JSF converters. The following screen shot is a screen shot of the application:

JSF Converters in Registration Application

This tutorial will discuss the following topics related to the use of JSF converters:

 

Partial Submit and Immediate Attributes

The partial submit attribute enables a component to perform a partial submit in the appropriate event for the component. This can be useful when it comes to conversion. By performing a partial submit after the component loses focus it will attempt to convert the data at that moment, if the data is not of the correct type an error message is displayed. This is opposed to the user cliking a submit command button. The following JSF code shows how to set the patial submit on a component:

          <ice:inputText partialSubmit="true"/>
      

The immediate attribute can be used to acheive the following effects:

Using the immediate attribute on a component means its value will be validated during the apply request values phase in the JSF lifecycle. Since conversion already occurs in this phase the use of this attribute when conversion is concerned is not needed. The immediate attribute is used more in validation instead of conversion.

 

How to User Standard JSF Converters

There are three standard JSF converters. The following is a list of the converters with their attributes:

For the standard converter tag, <f:converter/>, JSF has many standard data converters. The following is a sample of the id's of the data converters available:

To use the converter with a component, the converter must be nesting inside the components tag. The following JSF code shows how to add a standard converter for an inputText component:

          ...
          <ice:inputText id="age" value="#{user.age}" partialSubmit="true>
                <f:converter converterId="javax.faces.Integer"/>
          </ice:inputText>
          ...
      

This will now ensure that only integer values can be sent into the backing bean and not something else such as a character. In the screen shot below, you can see what happens when a non-integer value is entered.

Standard JSF Converter Error

When dealing with date data you must use the <f:convertDateTime/> converter tag. This will convert a string to a proper Date object. If the string entered in is not convertable then an error message will be displayed. The following JSF code is an example on how to implement a date converter:

          ...
          <ice:inputText id="birthdate" value="#{user.birthDate}">
                <f:convertDateTime dateStyle="short"/>
          </ice:inputText>
          ...
      

This will convert the entered in string to a short Date format. The following table displays all the standard formats available and what they look like:

Style Format
DEFAULT 26-Apr-99
SHORT 4/26/99
MEDIUM 26-Apr-99
LONG April 26, 1999
FULL Monday, April 26, 1999

In addition to converters for primatives, date, and time data types, JSF provides another converter for dealing with numbers such as percentages and currency. This converter deals with grouping, number of decimal digits, currency symbols, ect. The following JSF code shows how to add a number converter for dealing with currency:

          ...
          <ice:inputText id="salary" value="#{user.salary}">
                <f:convertNumber maxFractionDigits="2"
                                    groupingUsed="true"
                                    currencySymbol="$"
                                    maxIntegerDigits="7"
                                    type="currency"/*>
          </ice:inputText>
          ...
      

This will allow only whole numbers entered with a dollar sign and up to seven digits can only be entered at a time. Anything that breaches these conditions will cause a Conversion Error to be thrown.

Download the Demo Source:

 

How to Write a Custom Converters

Custom converters are nessesary if you need to convert field data into an application-specific object. There are five main steps in creating a custom converter.

  1. Implement the Converter instance(javax.faces.convert.Converter.
  2. Implement the getAsObject method, which converts a field (String) to an object.
  3. Implement the getAsString method, which converts an object to a String
  4. Register your custom converter in the faces context (faces-config.xml).
  5. Insert the converter into your JSP's with the <f:converter/> tag.

The following is a step-by-step walkthrough on how to create a custom converter.

Step 1: Implement the Converter interface

Create a utility class that will handle all of the conversion duties. This class must implement the Converter interfaces as shown below:

          import javax.faces.convert.Converter
          
          public class PhoneConverter implements Converter {
                ...
          }
      

Step 2: Implement the getAsObject Method

Here the getAsObject method converts a string to a PhoneNumber object

          public class PhoneConverter implements Converter {
                
                public Object getAsObject(FacesContext context, UIComponent component, String value){
                        if(StringUtils.isEmpty(value)){
                            return null;
                        }
                        
                        PhoneNumber phone = new PhoneNumber();
                        
                        String [] phoneComps = StringUtils.split(value," ,()-");
                        
                        String countryCode = phoneComps[0];
                        
                        phone.setCountryCode(countryCode);
                        
                        if(countryCode.equals("1")){
                            String areaCode = phoneComps[1];
                            String prefix = phoneComps[2];
                            String number = phoneComps[3];
                            phone.setAreaCode(areaCode);
                            phone.setPrefix(prefix);
                            phone.setNumber(number);
                        }
                        else {
                            phone.setNumber(value);
                        }
                        
                        return phone;
               }
          }
      

Step 3: Implement the getAsString method

Here the getAsString method converts a PhoneNumber object to a String.

          public class PhoneConverter implements Converter {
                ...
                public String getAsString(FacesContext context, UIComponent component, Object value){
                        return value.toString();
                }
          }
      

For the above code to work you must implement the objects (PhoneNumber) toString() method accordingly. For example:

          public class PhoneNumber {
                ...
                public String toString(){
                    if(countryCode.equals("1")){
                        return countryCode + "-" + areaCode + "-" + prefix + "-" + number;
                    }
                    else {
                        return number;
                    }
                }
           }
      

Step 4: Register Custom Converter with Faces Context

This step can be executed in two ways. Option one is to register the PhoneConverter class with a user defined id (icefaces.PhoneConverter). This id is used by <f:converter/> tags converterId attribute. To implement this, insert the following code into your faces-config.xml file:

          <converter>
                <converter-id>icefaces.PhoneConverter</converter-id>
                <converter-class>
                    com.icesoft.icefaces.tutorial.component.converter.custom.PhoneConverter
                </converter-class>
          </converter>
      

The other option is to register the PhoneConverter class to handle all PhoneNumber opbjects automaically. To do this insert the following code into your faces-config.xml file:

          <converter>
                <converter-for-class>
                    com.icesoft.icefaces.tutorial.component.converter.custom.PhoneNumber
                </converter-for-class>
                <converter-class>
                    com.icesoft.icefaces.tutorial.component.converter.custom.PhoneConverter
                </converter-class>
          </converter>
      

Step 5:Use the Converter Tag in your JSP

The last step is using the converter. This is very similar to using the standard JSF <f:converter> tag. For the first option from step four:

          <ice:inputText id="phone" value="#{user.phone}">
                <f:converter converterId="icefaces.PhoneConverter"/>
          </ice:inputText>
      

For the second option from step 4, there is no need to use the <f:converter/> tag since the PhoneConverter class handles all PhoneNumber objects automatically.

Download the Demo Source:

 

Message and Messages Tags

So far we have been using the <ice:messages/> tag to display all error messages at the bottom of the form. Now take for example if you enter more than one field incorrectly. There would only be one error message displayed and its not evident what input field the error occured in. To fix this we can use the <ice:message/> tag. By assigning this tag to a component with the for attribute, it will only display error messages for that component. Further more if we tie it in beside that component then it will be evident to the user if they have made a mistake in that input field. The following shows how to implement this to an inputTExt component:

           <ice:inputText id="age" value="#{user.age}">
                <f:converter converterId="javax.faces.Integer"/>
           </ice:inputText>
           <ice:message style="color:red;" id="ageError" for="age"/>
      

The screen shot below shows how it will look:

Error Message Tag

Custom Messages

The default messages that are supplies by JSF can be quite verbose and could couse confusion for end users. For conversion the default error message is "Conversion error occured" this could create confusion as to what exactly happened. To change the default message you can create your own message.properties file and switch out the message resource bundle in the faces context. The following code shows how to add the properties file to the faces context:

          <application>
                <locale-config>
                    <default-locale>en</default-locale>
                </locale-config>
                <message-bundle>
                    com.icesoft.icefaces.tutorial.component.converter.basic.messages
                </message-bundle>
          </application>
      

The following is the entry in the messages.properties file that will overide the default converter error message:

          ...
          javax.faces.component.UIInput.CONVERSION=invalid input
          ...
      

This will now display the message "invalid input" beside the field that is causing the error shown in the screen shot below.

Custom Error Message
 

Examples that Use JSF Converters

Example Source Notes
converter-basic converter-basic source code Simple example of how to use the standard JSF converters.
converter-custom converter-custom source code A custom converter is added to the converter-basic application.

The ICEfaces Tutorial
Table of Contents

Copyright 2006 ICEsoft Technologies Inc. All rights reserved.