org.springframework.validation
Class DataBinder

java.lang.Object
  extended by org.springframework.validation.DataBinder
All Implemented Interfaces:
PropertyEditorRegistry
Direct Known Subclasses:
WebDataBinder

public class DataBinder
extends Object
implements PropertyEditorRegistry

Binder that allows for binding property values to a target object. The binding process can be customized through specifying allowed fields, required fields, and custom editors.

Note that there are potential security implications in failing to set an array of allowed fields. In the case of HTTP form POST data for example, malicious clients can attempt to subvert an application by supplying values for fields or properties that do not exist on the form. In some cases this could lead to illegal data being set on command objects or their nested objects. For this reason, it is highly recommended to specify the allowedFields property on the DataBinder.

The binding results can be examined via the Errors interface, available as BindException instance. Missing field errors and property access exceptions will be converted to FieldErrors, collected in the Errors instance, with the following error codes:

Custom validation errors can be added afterwards. You will typically want to resolve such error codes into proper user-visible error messages; this can be achieved through resolving each error via a MessageSource. The list of message codes to try can be customized through the MessageCodesResolver strategy. DefaultMessageCodesResolver's javadoc gives details on the default resolution rules.

By default, binding errors are resolved through the binding error processor for required binding errors and property access exceptions. You can override those if needed, for example to generate different error codes.

This generic data binder can be used in any sort of environment. It is heavily used by Spring's web MVC controllers, via the subclass org.springframework.web.bind.ServletRequestDataBinder.

Author:
Rod Johnson, Juergen Hoeller
See Also:
setAllowedFields(java.lang.String[]), setRequiredFields(java.lang.String[]), registerCustomEditor(java.lang.Class, java.beans.PropertyEditor), setMessageCodesResolver(org.springframework.validation.MessageCodesResolver), setBindingErrorProcessor(org.springframework.validation.BindingErrorProcessor), bind(org.springframework.beans.PropertyValues), getErrors(), DefaultMessageCodesResolver, DefaultBindingErrorProcessor, MessageSource, ServletRequestDataBinder

Field Summary
static String DEFAULT_OBJECT_NAME
          Default object name used for binding: "target"
protected static Log logger
          We'll create a lot of DataBinder instances: Let's use a static logger.
 
Constructor Summary
DataBinder(Object target)
          Create a new DataBinder instance, with default object name.
DataBinder(Object target, String objectName)
          Create a new DataBinder instance.
 
Method Summary
protected  void applyPropertyValues(MutablePropertyValues mpvs)
          Apply given property values to the target object.
 void bind(PropertyValues pvs)
          Bind the given property values to this binder's target.
protected  void checkAllowedFields(MutablePropertyValues mpvs)
          Check the given property values against the allowed fields, removing values for fields that are not allowed.
protected  void checkRequiredFields(MutablePropertyValues mpvs)
          Check the given property values against the required fields, generating missing field errors where appropriate.
 Map close()
          Close this DataBinder, which may result in throwing a BindException if it encountered any errors
protected  BindException createErrors(Object target, String objectName)
          Create a new Errors instance for this data binder.
protected  void doBind(MutablePropertyValues mpvs)
          Actual implementation of the binding process, working with the passed-in MutablePropertyValues instance.
 PropertyEditor findCustomEditor(Class requiredType, String propertyPath)
          Find a custom property editor for the given type and property.
 String[] getAllowedFields()
          Return the fields that should be allowed for binding.
protected  BeanWrapper getBeanWrapper()
          Return the underlying BeanWrapper of the Errors object.
 BindingErrorProcessor getBindingErrorProcessor()
          Return the strategy for processing binding errors.
 BindException getErrors()
          Return the Errors instance for this data binder.
 String getObjectName()
          Return the name of the bound object.
 String[] getRequiredFields()
          Return the fields that are required for each binding process.
 Object getTarget()
          Return the wrapped target object.
protected  boolean isAllowed(String field)
          Return if the given field is allowed for binding.
 boolean isIgnoreUnknownFields()
          Return whether to ignore unknown fields, i.e. whether to ignore request parameters that don't have corresponding fields in the target object.
 void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)
          Register the given custom property editor for all properties of the given type.
 void registerCustomEditor(Class requiredType, String field, PropertyEditor propertyEditor)
          Register the given custom property editor for the given type and property, or for all properties of the given type.
 void setAllowedFields(String[] allowedFields)
          Register fields that should be allowed for binding.
 void setBindingErrorProcessor(BindingErrorProcessor bindingErrorProcessor)
          Set the strategy to use for processing binding errors, that is, required field errors and PropertyAccessExceptions.
 void setExtractOldValueForEditor(boolean extractOldValueForEditor)
          Set whether to extract the old field value when applying a property editor to a new value for a field.
 void setIgnoreUnknownFields(boolean ignoreUnknownFields)
          Set whether to ignore unknown fields, i.e. whether to ignore request parameters that don't have corresponding fields in the target object.
 void setMessageCodesResolver(MessageCodesResolver messageCodesResolver)
          Set the strategy to use for resolving errors into message codes.
 void setRequiredFields(String[] requiredFields)
          Register fields that are required for each binding process.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_OBJECT_NAME

public static final String DEFAULT_OBJECT_NAME
Default object name used for binding: "target"

See Also:
Constant Field Values

logger

protected static final Log logger
We'll create a lot of DataBinder instances: Let's use a static logger.

Constructor Detail

DataBinder

public DataBinder(Object target)
Create a new DataBinder instance, with default object name.

Parameters:
target - target object to bind onto
See Also:
DEFAULT_OBJECT_NAME

DataBinder

public DataBinder(Object target,
                  String objectName)
Create a new DataBinder instance.

Parameters:
target - target object to bind onto
objectName - name of the target object
Method Detail

createErrors

protected BindException createErrors(Object target,
                                     String objectName)
Create a new Errors instance for this data binder. Can be overridden in subclasses to. Needs to be a subclass of BindException.

Parameters:
target - target object to bind onto
objectName - name of the target object
Returns:
the Errors instance
See Also:
close()

getTarget

public Object getTarget()
Return the wrapped target object.


getObjectName

public String getObjectName()
Return the name of the bound object.


getErrors

public BindException getErrors()
Return the Errors instance for this data binder.

Returns:
the Errors instance, to be treated as Errors or as BindException
See Also:
Errors

getBeanWrapper

protected BeanWrapper getBeanWrapper()
Return the underlying BeanWrapper of the Errors object. To be used by binder subclasses that need bean property checks.


setIgnoreUnknownFields

public void setIgnoreUnknownFields(boolean ignoreUnknownFields)
Set whether to ignore unknown fields, i.e. whether to ignore request parameters that don't have corresponding fields in the target object.


isIgnoreUnknownFields

public boolean isIgnoreUnknownFields()
Return whether to ignore unknown fields, i.e. whether to ignore request parameters that don't have corresponding fields in the target object.


setAllowedFields

public void setAllowedFields(String[] allowedFields)
Register fields that should be allowed for binding. Default is all fields. Restrict this for example to avoid unwanted modifications by malicious users when binding HTTP request parameters.

Supports "xxx*" and "*xxx" patterns. More sophisticated matching can be implemented by overriding the isAllowed method.

Parameters:
allowedFields - array of field names
See Also:
ServletRequestDataBinder, isAllowed(java.lang.String)

getAllowedFields

public String[] getAllowedFields()
Return the fields that should be allowed for binding.

Returns:
array of field names

setRequiredFields

public void setRequiredFields(String[] requiredFields)
Register fields that are required for each binding process.

If one of the specified fields is not contained in the list of incoming property values, a corresponding "missing field" error will be created, with error code "required" (by the default binding error processor).

Parameters:
requiredFields - array of field names
See Also:
setBindingErrorProcessor(org.springframework.validation.BindingErrorProcessor), DefaultBindingErrorProcessor.MISSING_FIELD_ERROR_CODE

getRequiredFields

public String[] getRequiredFields()
Return the fields that are required for each binding process.

Returns:
array of field names

setExtractOldValueForEditor

public void setExtractOldValueForEditor(boolean extractOldValueForEditor)
Set whether to extract the old field value when applying a property editor to a new value for a field.

Default is "true", exposing previous field values to custom editors. Turn this to "false" to avoid side effects caused by getters.


registerCustomEditor

public void registerCustomEditor(Class requiredType,
                                 PropertyEditor propertyEditor)
Description copied from interface: PropertyEditorRegistry
Register the given custom property editor for all properties of the given type.

Specified by:
registerCustomEditor in interface PropertyEditorRegistry
Parameters:
requiredType - type of the property
propertyEditor - editor to register

registerCustomEditor

public void registerCustomEditor(Class requiredType,
                                 String field,
                                 PropertyEditor propertyEditor)
Description copied from interface: PropertyEditorRegistry
Register the given custom property editor for the given type and property, or for all properties of the given type.

If the property path denotes an array or Collection property, the editor will get applied either to the array/Collection itself (the PropertyEditor has to create an array or Collection value) or to each element (the PropertyEditor has to create the element type), depending on the specified required type.

Note: Only one single registered custom editor per property path is supported. In the case of a Collection/array, do not register an editor for both the Collection/array and each element on the same property.

For example, if you wanted to register an editor for "items[n].quantity" (for all values n), you would use "items.quality" as the value of the 'propertyPath' argument to this method.

Specified by:
registerCustomEditor in interface PropertyEditorRegistry
Parameters:
requiredType - type of the property (can be null if a property is given but should be specified in any case for consistency checking)
field - path of the property (name or nested path), or null if registering an editor for all properties of the given type
propertyEditor - editor to register

findCustomEditor

public PropertyEditor findCustomEditor(Class requiredType,
                                       String propertyPath)
Description copied from interface: PropertyEditorRegistry
Find a custom property editor for the given type and property.

Specified by:
findCustomEditor in interface PropertyEditorRegistry
Parameters:
requiredType - type of the property (can be null if a property is given but should be specified in any case for consistency checking)
propertyPath - path of the property (name or nested path), or null if looking for an editor for all properties of the given type
Returns:
the registered editor, or null if none

setMessageCodesResolver

public void setMessageCodesResolver(MessageCodesResolver messageCodesResolver)
Set the strategy to use for resolving errors into message codes. Applies the given strategy to the underlying errors holder.

Default is a DefaultMessageCodesResolver.

See Also:
BindException.setMessageCodesResolver(org.springframework.validation.MessageCodesResolver), DefaultMessageCodesResolver

setBindingErrorProcessor

public void setBindingErrorProcessor(BindingErrorProcessor bindingErrorProcessor)
Set the strategy to use for processing binding errors, that is, required field errors and PropertyAccessExceptions.

Default is a DefaultBindingErrorProcessor.

See Also:
DefaultBindingErrorProcessor

getBindingErrorProcessor

public BindingErrorProcessor getBindingErrorProcessor()
Return the strategy for processing binding errors.


bind

public void bind(PropertyValues pvs)
Bind the given property values to this binder's target.

This call can create field errors, representing basic binding errors like a required field (code "required"), or type mismatch between value and bean property (code "typeMismatch").

Note that the given PropertyValues should be a throwaway instance: For efficiency, it will be modified to just contain allowed fields if it implements the MutablePropertyValues interface; else, an internal mutable copy will be created for this purpose. Pass in a copy of the PropertyValues if you want your original instance to stay unmodified in any case.

Parameters:
pvs - property values to bind
See Also:
doBind(org.springframework.beans.MutablePropertyValues)

doBind

protected void doBind(MutablePropertyValues mpvs)
Actual implementation of the binding process, working with the passed-in MutablePropertyValues instance.

Parameters:
mpvs - the property values to bind, as MutablePropertyValues instance
See Also:
checkAllowedFields(org.springframework.beans.MutablePropertyValues), checkRequiredFields(org.springframework.beans.MutablePropertyValues), applyPropertyValues(org.springframework.beans.MutablePropertyValues)

checkAllowedFields

protected void checkAllowedFields(MutablePropertyValues mpvs)
Check the given property values against the allowed fields, removing values for fields that are not allowed.

Parameters:
mpvs - the property values to be bound (can be modified)
See Also:
getAllowedFields(), isAllowed(String)

isAllowed

protected boolean isAllowed(String field)
Return if the given field is allowed for binding. Invoked for each passed-in property value.

The default implementation checks for "xxx*" and "*xxx" matches. Can be overridden in subclasses.

If the field is found in the "allowedFields" array as direct match, this method will not be invoked.

Parameters:
field - the field to check
Returns:
if the field is allowed
See Also:
setAllowedFields(java.lang.String[])

checkRequiredFields

protected void checkRequiredFields(MutablePropertyValues mpvs)
Check the given property values against the required fields, generating missing field errors where appropriate.

Parameters:
mpvs - the property values to be bound (can be modified)
See Also:
getRequiredFields(), getBindingErrorProcessor(), BindingErrorProcessor.processMissingFieldError(java.lang.String, org.springframework.validation.BindException)

applyPropertyValues

protected void applyPropertyValues(MutablePropertyValues mpvs)
Apply given property values to the target object.

Default implementation applies all of the supplied property values as bean property values. By default, unknown fields will be ignored.

Parameters:
mpvs - the property values to be bound (can be modified)
See Also:
getTarget(), getBeanWrapper(), isIgnoreUnknownFields(), getBindingErrorProcessor(), BindingErrorProcessor.processPropertyAccessException(org.springframework.beans.PropertyAccessException, org.springframework.validation.BindException)

close

public Map close()
          throws BindException
Close this DataBinder, which may result in throwing a BindException if it encountered any errors

Returns:
the model Map, containing target object and Errors instance
Throws:
BindException - if there were any errors in the bind operation
See Also:
BindException.getModel()


Copyright (c) 2002-2007 The Spring Framework Project.