Wednesday, March 4, 2009

Spring DataBinding and PropertyEditors

To bind data from a <form> to a SimpleFormController is easy, just read Spring MVC Step by Step in the Spring distribution and they show you how to do it. But what happens when you need to translate strings that represent dates to Date objects? or translate from JSON string to an Object?


To that you'll need to create a custom PropertyEditor and override initBinder in SimpleFormController, to tell the controller how to handle the data that return from a HttpServletRequest object. By default it does a simple mapping, that is to say it tries to read the keys from HttpServletRequest and tries to find the corresponding setter in the commandClass and sets the value. If it can't it will generate a DataBinding error.


e.g


If the class has a setter named setText and the HttpSerlvetRequest has a parameter with the key "text", the binder will try to set the value of the key into the object specified by the commandClass.


Sample code from overiding initBinder using CustomDateEditor to read dates


protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder)throws Exception{
SimpleDateFormat df=new SimpleDateFormat("dd/MM/yyyy");
CustomDateEditor cde=new CustomDateEditor(df,true);
binder.setCustomEditor(Date.class,cde);
super.initBinder(request,binder);
}

I suggest you look at this presentation to get a feel of the workflow for the SimpleFormController. For Spring MVC it is important to know how the flow if the controller is so that you can understand how the various overrides will work.


For custom PropertyEditors you can look at the source for CustomDateEditor to get a feel how to implement. Most of the property editors will inherit from PropertyEditorSupport rather then implementing PropertyEditor staright.


It seems like the few methods that you will need to override are the setAsText and getAsText methods. And in these 2 methods you will need to use setValue and getValue to set the correct object so that the binder can retrive the final object. So a custom PropertyEditor might look something like this:


public class CustomEditor extends PropertyEditorSupport{

public CustomEditor(){}

public void setAsText(String text){

//Do some proccessing then call setValue(); to set the object
setValue(someObject);

}

public String getAsText(){

SomeObject obj=getValue();

//Do something to get the thing as text again

}

}

The only puzzling thing (at least to me) is why does Spring use the ProperyEditor interface for something that could probably be implemented by using a simpler interface consiting of the above 4 methods (setAsText,getAsText,setValue,getValue)? I have no idea it seems that lots of methods in the interface are not  being use and they could probably be served by using a simpler interface.


Links


CustomDateEditor source


No comments:

Post a Comment