diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java index 3a4a26ec199..3469d8506ab 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java @@ -79,11 +79,11 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor { PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException; /** - * Set if this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value. - *
If true, a null path location will be populated with a default object value and traversed + * Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value. + *
If "true", a null path location will be populated with a default object value and traversed * instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also - * enables auto-growth of collection elements when an index that is out of bounds is accessed. - *
Default is false. + * enables auto-growth of collection elements when accessing an out-of-bounds index. + *
Default is "false" on a plain BeanWrapper. */ void setAutoGrowNestedPaths(boolean autoGrowNestedPaths); diff --git a/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java b/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java index 0f77384f4e3..3437e672b9f 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java @@ -44,6 +44,8 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp private final Object target; + private final boolean autoGrowNestedPaths; + private transient BeanWrapper beanWrapper; @@ -53,8 +55,19 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp * @param objectName the name of the target object */ public BeanPropertyBindingResult(Object target, String objectName) { + this(target, objectName, true); + } + + /** + * Creates a new instance of the {@link BeanPropertyBindingResult} class. + * @param target the target bean to bind onto + * @param objectName the name of the target object + * @param autoGrowNestedPaths whether to "auto-grow" a nested path that contains a null value + */ + public BeanPropertyBindingResult(Object target, String objectName, boolean autoGrowNestedPaths) { super(objectName); this.target = target; + this.autoGrowNestedPaths = autoGrowNestedPaths; } @@ -73,7 +86,7 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp if (this.beanWrapper == null) { this.beanWrapper = createBeanWrapper(); this.beanWrapper.setExtractOldValueForEditor(true); - this.beanWrapper.setAutoGrowNestedPaths(true); + this.beanWrapper.setAutoGrowNestedPaths(this.autoGrowNestedPaths); } return this.beanWrapper; } diff --git a/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java b/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java index 6ee866ae281..b5d13ef1847 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java @@ -125,6 +125,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { private boolean ignoreInvalidFields = false; + private boolean autoGrowNestedPaths = true; + private String[] allowedFields; private String[] disallowedFields; @@ -182,7 +184,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { public void initBeanPropertyAccess() { Assert.isNull(this.bindingResult, "DataBinder is already initialized - call initBeanPropertyAccess before any other configuration methods"); - this.bindingResult = new BeanPropertyBindingResult(getTarget(), getObjectName()); + this.bindingResult = new BeanPropertyBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths()); if (this.conversionService != null) { this.bindingResult.initConversion(this.conversionService); } @@ -330,6 +332,25 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { return this.ignoreInvalidFields; } + /** + * Set whether this binder should attempt to "auto-grow" a nested path that contains a null value. + *
If "true", a null path location will be populated with a default object value and traversed + * instead of resulting in an exception. This flag also enables auto-growth of collection elements + * when accessing an out-of-bounds index. + *
Default is "true" on a standard DataBinder. + * @see org.springframework.beans.BeanWrapper#setAutoGrowNestedPaths + */ + public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) { + this.autoGrowNestedPaths = autoGrowNestedPaths; + } + + /** + * Return whether "auto-growing" of nested paths has been activated. + */ + public boolean isAutoGrowNestedPaths() { + return this.autoGrowNestedPaths; + } + /** * Register fields that should be allowed for binding. Default is all * fields. Restrict this for example to avoid unwanted modifications