After trying to figure out how to use the fieldMarkerPrefix feature in WebDataBinder I have come to the conclusion that it doesn't do anything usefull. Here is why:
Consider the case where the data in our MutablePropertyValues mpvs looks like this:
Code:
_colors [#ffffff,#fsd234]
As part of the doBind() method of WebDataBinder checkFieldMarkers() is called. It does exactly what it says it will do.
Code:
/**
* Check the given property values for field markers,
* i.e. for fields that start with the field marker prefix.
* <p>The existence of a field marker indicates that the specified
* field existed in the form. If the property values do not contain
* a corresponding field value, the field will be considered as empty
* and will be reset appropriately.
* @param mpvs the property values to be bound (can be modified)
* @see #getFieldMarkerPrefix
* @see #getEmptyValue(String, Class)
*/
And leaves our mpvs looking like this:
Code:
_colors [#ffffff,#fsd234]
colors []
We go further along with the binding process and end up binding an empty collection to the colors property of the command object, when a collection with two colors should have been bound. Although this is correct according to the javadoc, it does not accomplish the task at hand.
Furthermore WebDataBinder's checkFieldMarkers() method depends on the getEmptyValue(String field, Class fieldType) method, the default implementation of which returns null if the field type is a Collection. Also rather inconvenient.
I have solved the problem at hand by subclassing ServletRequestDataBinder. Here is the result:
Code:
public class DefaultValueServletRequestDataBinder extends ServletRequestDataBinder
{
private PropertyValue[] defaultValues;
/**
* Create a new ServletRequestDataBinder instance.
*
* @param target target object to bind onto
* @param objectName objectName of the target object
*/
public DefaultValueServletRequestDataBinder(Object target, String objectName)
{
super(target, objectName);
}
public void setDefaultValues(PropertyValue[] values)
{
this.defaultValues = values;
}
protected void doBind(MutablePropertyValues mpvs)
{
if(defaultValues != null)
{
for(PropertyValue property : defaultValues)
{
if(!mpvs.contains(property.getName())) mpvs.addPropertyValue(property);
}
}
super.doBind(mpvs);
}
}
Although this approach requires changing your Controller classes slightly to use the new DefaultValueServletRequestDataBinder, it works, and in my opinion is more convenient.