org.springframework.validation
Class DataBinder

java.lang.Object
  extended byorg.springframework.validation.DataBinder
Direct Known Subclasses:
ServletRequestDataBinder

public class DataBinder
extends Object

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.

This generic data binder can be used in any sort of environment. It is heavily used by Spring's web binding features, via the subclass 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), bind(org.springframework.beans.PropertyValues), getErrors(), DefaultMessageCodesResolver, MessageSource, ServletRequestDataBinder

Field Summary
protected static Log logger
          We'll create a lot of DataBinder instances: Let's use a static logger.
static String METHOD_INVOCATION_ERROR_CODE
          Error code that a type mismatch error (i.e. a property value not matching the type of the target field) will be registered with: "methodInvocation".
static String MISSING_FIELD_ERROR_CODE
          Error code that a missing field error (i.e. a required field not found in the list of property values) will be registered with: "required".
static String TYPE_MISMATCH_ERROR_CODE
          Error code that a type mismatch error (i.e. a property value not matching the type of the target field) will be registered with: "typeMismatch".
 
Constructor Summary
DataBinder(Object target, String objectName)
          Create a new DataBinder instance.
 
Method Summary
 void bind(PropertyValues pvs)
          Bind the given property values to this binder's target.
 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.
 String[] getAllowedFields()
          Return the fields that should be allowed for binding.
protected  Object[] getArgumentsForBindingError(String field)
          Return FieldError arguments for a binding error on the given field.
protected  BeanWrapper getBeanWrapper()
          Return the underlying BeanWrapper of the Errors object.
 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.
 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 field, or for all fields of the given type.
 void setAllowedFields(String[] allowedFields)
          Register fields that should be allowed for binding.
 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

MISSING_FIELD_ERROR_CODE

public static final String MISSING_FIELD_ERROR_CODE
Error code that a missing field error (i.e. a required field not found in the list of property values) will be registered with: "required".

See Also:
Constant Field Values

TYPE_MISMATCH_ERROR_CODE

public static final String TYPE_MISMATCH_ERROR_CODE
Error code that a type mismatch error (i.e. a property value not matching the type of the target field) will be registered with: "typeMismatch".

See Also:
TypeMismatchException.ERROR_CODE, Constant Field Values

METHOD_INVOCATION_ERROR_CODE

public static final String METHOD_INVOCATION_ERROR_CODE
Error code that a type mismatch error (i.e. a property value not matching the type of the target field) will be registered with: "methodInvocation".

See Also:
MethodInvocationException.ERROR_CODE, 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,
                  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.


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.

Parameters:
requiredFields - array of field names

getRequiredFields

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

Returns:
array of field names

registerCustomEditor

public void registerCustomEditor(Class requiredType,
                                 PropertyEditor propertyEditor)
Register the given custom property editor for all properties of the given type.

Parameters:
requiredType - type of the property
propertyEditor - editor to register
See Also:
BeanWrapper.registerCustomEditor(java.lang.Class, java.beans.PropertyEditor)

registerCustomEditor

public void registerCustomEditor(Class requiredType,
                                 String field,
                                 PropertyEditor propertyEditor)
Register the given custom property editor for the given type and field, or for all fields of the given type.

If the field denotes an array or Collection, the PropertyEditor 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 case of a Collection/array, do not register an editor for both the Collection/array and each element on the same property.

Parameters:
requiredType - type of the property (can be null if a field is given but should be specified in any case for consistency checking)
field - name of the field (can also be a nested path), or null if registering an editor for all fields of the given type
propertyEditor - editor to register
See Also:
BeanWrapper.registerCustomEditor(java.lang.Class, java.beans.PropertyEditor)

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.

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

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.

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[])

getArgumentsForBindingError

protected Object[] getArgumentsForBindingError(String field)
Return FieldError arguments for a binding error on the given field. Invoked for each missing required fields and each type mismatch.

Default implementation returns a DefaultMessageSourceResolvable with "objectName.field" and "field" as codes.

Parameters:
field - the field that caused the binding error
Returns:
the Object array that represents the FieldError arguments
See Also:
DefaultMessageSourceResolvable.getArguments(), DefaultMessageSourceResolvable

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) 2003-2004 The Spring Framework Project.