RSS Feed Subscribe to RSS Feed

 

Data binding in Spring MVC

Two of the most important tasks carried out by Spring MVC when you submit a form are Data binding and validation.
The following article discusses data binding, including the use of custom PropertyEditors, and some of the options available for registering such editors. Most of the information discussed applies to Spring in general, but its application in Spring MVC is my primary interest.

In a future article I would like to discuss validation including the use of custom error messages.

Note that these notes relate to version 2.5.6 of Spring, the latest production code at time of writing, and depend heavily on the corresponding Spring reference docs.



Data Binding

Spring MVC allows the use of command objects (aka form backing objects, model attributes, domain model objects – basically the objects used to transport data between your view and your controller) using just about any type. However, the Servlet API deals with form parameters as Strings. Spring uses a technique called data binding to covert between the String representation and the real underlying type. This enables user input to be bound to the objects you use to process user input. In other words, the values entered by a user in a form can be used to set the property values on a chosen object.
As well as binding the values, Spring includes support for validation and binding result analysis.

The binding functionality is provided by Spring’s org.springframework.validation.DataBinder class.
And when converting a String to some arbitrary type, DataBinders make use of ProperEditors. PropertyEditors are not Spring specific, but rather part of the JavaBeans API.

Using PropertyEditors

Spring heavily uses the concept of PropertyEditors to effect the conversion between an Object and a String.
Spring has a number of built-in PropertyEditors to make life easy (for a complete list, see here).
If you are using a custom type that Spring is unable to convert to and from a String, you will likely receive a lovely error such as this:

org.springframework.web.bind.ServletRequestBindingException: Errors binding onto object ‘dependsOnExoticType’; nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object ‘dependsOnExoticType’ on field ‘type’: rejected value [test]; codes [typeMismatch.dependsOnExoticType.type,typeMismatch.type,typeMismatch.example.ExoticType,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dependsOnExoticType.type,type]; arguments []; default message [type]]; default message [Failed to convert property value of type [java.lang.String] to required type [example.ExoticType] for property ‘type’; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [example.ExoticType] for property ‘type’: no matching editors or conversion strategy found]

The solution is to create your own custom editor.

Creating a custom property editor

A custom property editor should be of type java.beans.PropertyEditor. It tells Spring how to convert to a String and back again. As an example, see the ExoticTypeEditor in the Spring reference docs here.

The question is then how to register the custom editor.

Registering your custom editor

There are several ways to ensure you custom editor gets registered.

1) Put Editor in same package

The simplest way (by far!) is to put the Editor in the same package as the class it handles. This is because the standard JavaBeans infrastructure will automatically discover PropertyEditor classes (without you having to register them explicitly) if they are in the same package as the class they handle, and have the same name as that class, with’Editor’ appended;

However, if putting the Editor in the same package as the class it handlers is not possible (If for example, you are using a custom type from a 3rd party library and hence you don’t have access to the source code), try one of the other options below…

2) CustomEditorConfigurer

Another approach to registering a custom PropertyEditor is to use a special bean factory post-processor called CustomEditorConfigurer.
This is the approach used in the spring reference manual for the ‘ExoticType’ example. Again, see
section 5.4.2.1. Registering additional custom PropertyEditors, here.

The CustomEditorConfigurer is used to register the new PropertyEditor with the ApplicationContext, which will then be able to use it as needed.

Gotchas

i) Won’t work with BeanFactory – only ApplicationContext
The PropertyEditors defined in the ‘customEditorConfigurer’ bean will only be automatically used if you are using an ApplicationContext implementation (i.e. will not work for BeanFactory). This is discussed here.
ii) Only works for ApplicationContext created beans – not data binding beans such as form objects
This approach only works for beans created by the ApplicationContext. The PropertyEditors that are registered via CustomEditorConfigurer are NOT available for use in the data binding infrastructure (this is discussed here and here).
I think this should be made more clear in the spring framework ref docs (although, in fairness, it is covered in the CustomEditorConfigure javadocs).

So, if you are using Spring MVC and dealing with form submission, the next option may be better…

3) Explicitly register your editor in initBinder

So, a better approach, as far as form data binding is concerned, is to explicitly register your editor within initBinder() in the relevant Controller. e.g.


@Controller
@RequestMapping("/exoticView.htm")
public class TestController {
	
	//post and get handling methods etc...

	@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
		binder.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
	}

}

4) Use a WebBindingInitializer

If you find yourself using the above approach (registering your customer editor in initBinder) in many controllers, and you use a annotation based controller (Spring 2.5+), then you can use a WebBindingInitializer to register global property editors.

To do this, create a class that implements the WebBindingInitializer interface, for example


public class GlobalBindingInitializer implements WebBindingInitializer {

    public void initBinder(WebDataBinder binder, WebRequest request) {
        binder.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
    }

}

Then update your web application context file to contain:



    
        
    


I discovered this approach in a posting on StackOverflow about hidden features of Spring . It means you can register an editor once and use it anywhere. This is now my preferred way to register custom property editors.

5) Use PropertyEditorRegistrar

Another mechanism for registering property editors with the Spring container, and the final one in the Spring reference docs, is to create and use a PropertyEditorRegistrar. See section 5.4.2.1.1 here. The docs say that this is a good approach “when you need to use the same set of property editors in several different situations”. I have used this approach successfully in the past, but to be honest, I don’t quite see the benefits beyond the GlobalBindingInitializer approach above and it seems to require a few more steps. (I also saw some confusing debate on exactly what steps are mandatory here)

6) BeanInfo

There is also a BeanInfo mechanism mentioned in the Spring docs which I admit I have never tried – or fully understood.

Tags: ,

5 Responses to “Data binding in Spring MVC”

  1. Danny |

    Spring 3.0 adds a new mechanism for data binding–two actually. Referred to as core.convert and ui.format. Core.convert handles one-way conversions and ui.format takes care of back-and-forth–the typical use case using web forms.

    Definitely worth a look: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch05s06.html

  2. admin |

    Thanks Danny. From the docs: “Use Formatters when you’re working in a UI environment such as a HTML form of a web application, and need to apply two-way parsing, formatting, and localization logic to form field values.”

    Sounds perfect. And hopefully a little simpler than some of the approaches I discuss above from 2.5.x.

    Another reason to migrate to Spring 3.0 when the production release is ready…

    Shaun

  3. Data binding in Spring MVC « |

    […] Data binding in Spring MVC A good introduction to  “Data binding in Spring MVC”. […]

  4. Java bookmark links, Nov 2009 – Week1 | bookmark-link |

    […] 05 Nov 09 – Shaun Abram blog about the Spring’s data binding, and how to create and register custom property editor in […]

  5. redsonic |

    Thanks for this great article !

Leave a Reply