Phil Webb's Blog

Random thoughts from a software developer

Integrating Spring & JavaServer Faces : Converters

with 2 comments

When working with any web framework, you invariable run into the need to convert data input by the user from a String to some other type. Both Spring and JSF have converter strategies to deal with this, although they are really quite different in both their design and capabilities. Lets start by looking at Spring.

Spring 3 introduced a whole new conversion framework that allows objects of any type to be converted to any other type (as long as an appropriate converter is registered). Keith Donald has written about how the new conversion process works. Spring MVC was also updated at version 3 to make use of the converter service when dealing with request parameters, for example, passing a String parameter to the following controller method:

@RequestMapping
public void example(@RequestParam Integer value)

will result in the StringToNumber converter (via the StringToNumberConverterFactory) running to create the equivalent Integer.

Unlike Spring, converters in JSF only deal with converting objects to and from Strings. The javax.faces.convert.Converter interface defines two methods: getAsString (used when rendering) converts an object to a string and getAsObject (used when decoding postbacks) converts a previously rendered string back to an object.

By default, you can register converters with JSF either by adding an entries to your faces-config.xml or by using the @FacesConverter annotation. I have been working to allow you to also register JSF converters by simply declaring them as Spring beans. Using Spring beans gives you a number of advantages over vanilla JSF. For example, you easily can inject other collaborator beans and you can use Spring AOP. To use the converter bean simply refer to its ID from JSF:

@Component
public class MyConverter implements Converter {
    @Autowire
    private MyHelper helper;
    ...
}
<h:inputText value=”#{bean.value}”>
    <f:converter converterId=”myConverter”/>
</h:inputText>

In order to save referencing the same converter ID over and over again, JSF allows you to register a converter “for” a particular class. To support this with Spring a new @ForClass annotation has been introduced:

@Component
@ForClass(MyCustomType.class)
public class MyConverter implements Converter {
    ...
}

The example above will use MyConverter every time an object of MyCustomType needs converting.

For convenience I have also provided a variant of javax.faces.convert.Converter that supports generics. The org.springframework.springfaces.convert.Converter interface has an identical signature to the standard JSF version. When using this interface with @ForClass you can also omit the value on the annotation:

@Component
@ForClass
public class MyConverter implements Converter<MyCustomType> {
    ...
}

You can also implement more complex “for class” bindings using the ConditionalForClass interface (see the JavaDoc for details).

Finally, there is also support for using JSF converters (no matter how they are registered) from Spring MVC. The GenericFacesConverter is a Spring ConditionalGenericConverter that, when registered, automatically delegates to JSF.

For example, assuming that MyConverter is registered for MyCustomType the following MVC mapping will work:

@RequestMapping("/example")
public void example(@RequestParam MyCustomType value) {
    ....
}

You can also use the @FacesConverterId annotation if you need to reference a specific JSF converter:

@RequestMapping("/example")
public void example(@RequestParam @FacesConverterId("myOtherConverter") MyOtherCustomType value) {
    ....
}

If you want to see this in action take a look at ConverterExampleController from the showcase application.

About these ads

Written by Phillip Webb

October 8, 2011 at 4:30 pm

2 Responses

Subscribe to comments with RSS.

  1. Is there a maven archetype for spring – jsf or spring webflow project?

    voodoorider

    April 25, 2012 at 11:04 am

    • The examples here are a work in progress and have not been released. I am not sure if there are maven archetypes for standard JSF/Web Flow projects. There is a demo app for web flow called booking-faces that is shipped with the release.

      Phillip Webb

      April 25, 2012 at 11:11 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: