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.Date` or `java.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.Date` might 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 `UIInput` component is automatically converted to a `Number` when it is rendered with the `Number` renderer. Similarly, a `UIInput` component that is rendered with the `Date` renderer is automatically converted to a `Date`.

> The page author selects the component/renderer combination by choosing the appropriate tag: `input_number` for a `UIInput`/`Number` combination and `input_date` for a `UIInput`/`Date` combination. 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 `Converter` implementation on certain component/renderer combinations. These combinations are: `UIInput`/`Text`, `UIInput`/`Secret`, `UIInput`/`Hidden`, and `UIOutput`/`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`, or `output_text` tag to perform conversions.

> The `Converter` converts the data between the two views. You can either use the standard converters supplied with the JavaServer Faces implementation or create your own custom `Converter`. This section describes how to use the standard `Converter` implementations and explains an example of a custom `Converter`.

> ### Using the Standard Converters

> The JavaServer Faces implementation provides a set of `Converter` implementations that you can use to convert your component data to a type not supported by its renderer. The page author can apply a `Converter` to a component's value by setting the component tag's `converter` attribute to the identifier of the `Converter`. In addition, the page author can customize the behavior of the `Converter` with an `attribute` tag, which specifies the format of the converted value. The following tag is an example of applying a `Number` converter to a component and specifying the format of the `Number`:

>     <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 `salePrice` component's value is converted to a `Number` with a currency format. Table 21-16 lists all of the standard `Converter` identifiers, 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 Attributes
> --- | --- | --- | ---
> `Boolean` | `none` |  |
> `Date` | `dateStyle` | `java.text.DateFormat` | `short``,` `medium``,` `long``,` `full`. Default: `short`
> `timezone` | `java.util.TimeZone` | See `java.util.TimeZone`
> `DateFormat` | `formatPattern` | `java.text.DateFormat` | See the Formatting lesson in The Java Tutorial
> `timezone` | `java.util.TimeZone` | See `java.util.TimeZone`
> `DateTime` | `dateStyle` | `java.text.DateFormat` | `short``,` `medium``,` `long``,` `full` Default: `short`
> `timeStyle` | `java.text.DateFormat` | `short``,` `medium``,` `long``,` `full`. Default: `short`
> `timezone` | `java.util.TimeZone` | See `java.util.TimeZone`
> `Number` | `numberStyle` | `java.text.NumberFormat` | `currency``,` `integer``,` `number``,` `percent` Default: `integer`
> `NumberFormat` | `formatPattern` | `java.text.NumberFormat` | See the Formatting lesson in The Java Tutorial.
> `Time` | `timeStyle` | `java.text.DateFormat` | `short``,` `medium``,` `long``,` `full`. Default: `short`
> `timezone` | `java.util.TimeZone` | See `java.util.TimeZone`

> ### Creating and Using a Custom Converter

> If the standard `Converter` implementations don't perform the kind of data conversion you need to perform, you can easily create a custom `Converter` implementation for this purpose. To create and use a custom `Converter`, you need to perform these steps:

> 1. Implement the `Converter` interface
> 2. Register the `Converter` with application
> 3. Use the `Converter` in the page

> The `cardemo` application uses a custom `Converter`, called `CreditCardConverter`, 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 `Converter` interface. 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 `Converter` implementation must implement the `getAsObject(FacesContext, UIComponent, String)` method from the `Converter` interface. Here is the implementation of this method from `CreditCardConverter`:

>     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' `decode` methods are processed, the JavaServer Faces implementation looks up the component's local value in the request and calls the `getAsObject` method. When calling this method, the JavaServer Faces implementation passes in the current `FacesContext`, the component whose data needs conversion, and the local value as a `String`. The method then writes the local value to a character array, trims the dashes and blanks, adds the rest of the characters to a `String`, and returns the `String`.

> To define how the data is converted from the model view to the presentation view, the `Converter` implementation must implement the `getAsString(FacesContext, UIComponent, Object)` method from the `Converter` interface. Here is the implementation of this method from `CreditCardConverter`:

>     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' `encode` methods are called, the JavaServer Faces implementation calls the `getAsString` method in order to generate the appropriate output. When the JavaServer Faces implementation calls this method, it passes in the current `FacesContext`, the `UIComponent` whose value needs to be converted, and the model object value to be converted. Since this `Converter` does a `String`-to-`String` conversion, this method can cast the model object value to a `String`. It then reads the `String` to 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 the `converter` declaration from the application configuration file:

>     <converter>
>       <description>CreditCard Converter</description>
>       <converter-id>creditcard</converter-id>
>       <converter-class>
>         cardemo.CreditCardConverter
>       </converter-class>
>     </converter>

> The `converter` element represents a `Converter` implementation. The `converter` element contains required `converter-id` and `converter-class` elements.

> The `converter-id` element identifies an ID that is used by the `converter` attribute of a UI component tag to apply the converter to the component's data.

> The `converter-class` element identifies the `Converter` implementation.

> #### Use the Converter in the Page

> To apply the data conversion performed by your `Converter` to a particular component's value, you need to set the `converter` attribute of the component's tag to the `Converter` implementation's identifier. You provided this identifier when you registered the `Converter` with the application, as explained in the previous section.

> The identifier for the `CreditCardConverter` is `creditcard`. The `CreditCardConverter` is attached to the `ccno` component, as shown in this tag from the `Customer.jsp` page:

>     <h:input_text id="ccno" size="16"
>       converter="creditcard" >
>       ...
>     </h:input_text>

> By setting the `converter` attribute of a component's tag to the identifier of a `Converter`, you cause that component's local value to be automatically converted according to the rules specified in the `Converter`.

> A page author can use the same custom `Converter` for any similar component by simply supplying the `Converter` implementation's identifier to the `converter` attribute 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.