|
Download
FAQ History |
|
API
Search Feedback |
Performing Data Conversions
A typical Web application must deal with two different viewpoints of the underlying data being manipulated by the user interface:
- The model view, in which data is represented as native Java types, such as
java.util.Dateorjava.util.Number.- The presentation view, in which data is represented in a manner that can be read or modified by the user. For example, a
java.util.Datemight be represented as a text string in the format mm/dd/yy or as a set of three text strings.The JavaServer Faces implementation automatically converts component data between these two views through the component's renderer. For example, a
UIInputcomponent is automatically converted to aNumberwhen it is rendered with theNumberrenderer. Similarly, aUIInputcomponent that is rendered with theDaterenderer is automatically converted to aDate.The page author selects the component/renderer combination by choosing the appropriate tag:
input_numberfor aUIInput/Numbercombination andinput_datefor aUIInput/Datecombination. It is the application developer's responsibility to ensure that the model object property associated with the component is of the same type as that generated by the renderer.Sometimes you might want to convert a component's data to a type not supported by the component's renderer, or you might want to convert the format of the data. To facilitate this, JavaServer Faces technology allows you to register a
Converterimplementation on certain component/renderer combinations. These combinations are:UIInput/Text,UIInput/Secret,UIInput/Hidden, andUIOutput/Text.
Note: In a future release, the mechanism of using component/renderer combinations to perform conversions might be removed. Instead, the page author would register a converter on a component associated with an
input_text,input_secret,input_hidden, oroutput_texttag to perform conversions.
The
Converterconverts the data between the two views. You can either use the standard converters supplied with the JavaServer Faces implementation or create your own customConverter. This section describes how to use the standardConverterimplementations and explains an example of a customConverter.Using the Standard Converters
The JavaServer Faces implementation provides a set of
Converterimplementations that you can use to convert your component data to a type not supported by its renderer. The page author can apply aConverterto a component's value by setting the component tag'sconverterattribute to the identifier of theConverter. In addition, the page author can customize the behavior of theConverterwith anattributetag, which specifies the format of the converted value. The following tag is an example of applying aNumberconverter to a component and specifying the format of theNumber:<h:input_text id="salePrice" valueRef="LoginBean.sale" converter="Number"> <f:attribute name="numberStyle" value="currency"/> </h:input_text>As shown in the tag above, the
salePricecomponent's value is converted to aNumberwith a currency format. Table 21-16 lists all of the standardConverteridentifiers, the attributes you can use to customize the behavior of the converter, and the acceptable values for the format of the data.
Table 21-16 Standard Converter Implementations Converter Identifier Configuration Attributes Pattern Defined by Valid Values for AttributesBooleannoneDatedateStylejava.text.DateFormatshort,medium,long,full.Default:shorttimezonejava.util.TimeZone Seejava.util.TimeZoneDateFormatformatPatternjava.text.DateFormat See the Formatting lesson in The Java Tutorialtimezonejava.util.TimeZone Seejava.util.TimeZoneDateTimedateStylejava.text.DateFormatshort,medium,long,fullDefault:shorttimeStylejava.text.DateFormatshort,medium,long,full.Default:shorttimezonejava.util.TimeZone Seejava.util.TimeZoneNumbernumberStylejava.text.NumberFormatcurrency,integer,number,percentDefault:integerNumberFormatformatPatternjava.text.NumberFormat See the Formatting lesson in The Java Tutorial.TimetimeStylejava.text.DateFormatshort,medium,long,full.Default:shorttimezonejava.util.TimeZone Seejava.util.TimeZone
Creating and Using a Custom Converter
If the standard
Converterimplementations don't perform the kind of data conversion you need to perform, you can easily create a customConverterimplementation for this purpose. To create and use a customConverter, you need to perform these steps:The
cardemoapplication uses a customConverter, calledCreditCardConverter, to convert the data entered in the Credit Card Number field. It strips blanks and dashes from the text string and formats the text string so that a blank space separates every four characters. This section explains how this converter works.Implement the Converter Interface
All custom converters must implement the
Converterinterface. This implementation--at a minimum--must define how to convert data both ways between the two views of the data.To define how the data is converted from the presentation view to the model view, the
Converterimplementation must implement thegetAsObject(FacesContext, UIComponent, String)method from theConverterinterface. Here is the implementation of this method fromCreditCardConverter:public Object getAsObject(FacesContext context, UIComponent component, String newValue) throws ConverterException { String convertedValue = null; if ( newValue == null ) { return newValue; } convertedValue = newValue.trim(); if ( ((convertedValue.indexOf("-")) != -1) || ((convertedValue.indexOf(" ")) != -1)) { char[] input = convertedValue.toCharArray(); StringBuffer buffer = new StringBuffer(50); for ( int i = 0; i < input.length; ++i ) { if ( input[i] == '-' || input[i] == ' ' ) { continue; } else { buffer.append(input[i]); } } convertedValue = buffer.toString(); } return convertedValue; }During the Apply Request Values phase, when the components'
decodemethods are processed, the JavaServer Faces implementation looks up the component's local value in the request and calls thegetAsObjectmethod. When calling this method, the JavaServer Faces implementation passes in the currentFacesContext, the component whose data needs conversion, and the local value as aString. The method then writes the local value to a character array, trims the dashes and blanks, adds the rest of the characters to aString, and returns theString.To define how the data is converted from the model view to the presentation view, the
Converterimplementation must implement thegetAsString(FacesContext, UIComponent, Object)method from theConverterinterface. Here is the implementation of this method fromCreditCardConverter:public String getAsString(FacesContext context, UIComponent component,Object value) throws ConverterException { String inputVal = null; if ( value == null ) { return null; } try { inputVal = (String)value; } catch (ClassCastException ce) { throw new ConverterException(Util.getExceptionMessage( Util.CONVERSION_ERROR_MESSAGE_ID)); } char[] input = inputVal.toCharArray(); StringBuffer buffer = new StringBuffer(50); for ( int i = 0; i < input.length; ++i ) { if ( (i % 4) == 0 && i != 0) { if (input[i] != ' ' || input[i] != '-'){ buffer.append(" "); } else if (input[i] == '-') { buffer.append(" "); } } buffer.append(input[i]); } String convertedValue = buffer.toString(); return convertedValue; }During the Render Response phase, in which the components'
encodemethods are called, the JavaServer Faces implementation calls thegetAsStringmethod in order to generate the appropriate output. When the JavaServer Faces implementation calls this method, it passes in the currentFacesContext, theUIComponentwhose value needs to be converted, and the model object value to be converted. Since thisConverterdoes aString-to-Stringconversion, this method can cast the model object value to aString. It then reads theStringto a character array and loops through the array, adding a space after every four characters.Register the Converter
When you create a custom
Converter, you need to register it with the application. Here is theconverterdeclaration from the application configuration file:<converter> <description>CreditCard Converter</description> <converter-id>creditcard</converter-id> <converter-class> cardemo.CreditCardConverter </converter-class> </converter>The
converterelement represents aConverterimplementation. Theconverterelement contains requiredconverter-idandconverter-classelements.The
converter-idelement identifies an ID that is used by theconverterattribute of a UI component tag to apply the converter to the component's data.The
converter-classelement identifies theConverterimplementation.Use the Converter in the Page
To apply the data conversion performed by your
Converterto a particular component's value, you need to set theconverterattribute of the component's tag to theConverterimplementation's identifier. You provided this identifier when you registered theConverterwith the application, as explained in the previous section.The identifier for the
CreditCardConverteriscreditcard. TheCreditCardConverteris attached to theccnocomponent, as shown in this tag from theCustomer.jsppage:By setting the
converterattribute of a component's tag to the identifier of aConverter, you cause that component's local value to be automatically converted according to the rules specified in theConverter.A page author can use the same custom
Converterfor any similar component by simply supplying theConverterimplementation's identifier to theconverterattribute of the component's 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.