Download PDF Home History |  | API Search Feedback FAQ

> ## Creating a Custom Converter

> As explained in Conversion Model, if the standard converters included with JavaServer Faces technology don't perform the data conversion that you need, you can easily create a custom converter to perform this specialized conversion.

> 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 described in Conversion Model.

> This section explains how to implement the `Converter` interface to perform a custom data conversion. To make this implementation available to the application, the application architect registers it with the application, as explained in Registering a Custom Converter. To use the implementation, the page author must register it on a component, as explained in Using a Custom Converter.

> The Duke's Bookstore application uses a custom `Converter` implementation, called `CreditCardConverter`, to convert the data entered in the Credit Card Number field on the `bookcashier.jsp` page. It strips blanks and hyphens from the text string and formats it so that a blank space separates every four characters.

> 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;
>       }
>       // Since this is only a String to String conversion,
>       // this conversion does not throw ConverterException.

>       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` instance, 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 hyphens 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;
>       }
>       // value must be of the type that can be cast to a String.
>       try {
>         inputVal = (String)value;
>       } catch (ClassCastException ce) {
>         FacesMessage errMsg = MessageFactory.getMessage(
>         CONVERSION_ERROR_MESSAGE_ID,
>         (new Object[] { value, inputVal }));
>         throw new ConverterException(errMsg.getSummary());
>       }
>       // insert spaces after every four characters for better
>       // readability if it doesn't already exist.
>       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(" ");
>             // if there are any "-"'s convert them to blanks.
>           } 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 bean value to be converted. Because this converter does a `String`-to-`String` conversion, this method can cast the bean value to a `String`.

> If the value cannot be converted to a `String`, the method throws an exception, passing the error message from the `ResourceBundle`, which is registered with the application. Registering Messages explains how to register the error messages with the application. Performing Localization explains more about working with localized messages.

> If the value can be converted to a `String`, the method reads the `String` to a character array and loops through the array, adding a space after every four characters.

Download PDF Home History |  | API Search Feedback FAQ

All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.