DataBinder uses a default limit of 256 for array/collection auto-growing (SPR-7842)

This commit is contained in:
Juergen Hoeller
2011-07-03 19:26:49 +00:00
parent 022ac3166c
commit 4c75054f90
6 changed files with 152 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,8 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
private final boolean autoGrowNestedPaths;
private final int autoGrowCollectionLimit;
private transient BeanWrapper beanWrapper;
@@ -56,7 +58,7 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
* @param objectName the name of the target object
*/
public BeanPropertyBindingResult(Object target, String objectName) {
this(target, objectName, true);
this(target, objectName, true, Integer.MAX_VALUE);
}
/**
@@ -64,11 +66,13 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
* @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
* @param autoGrowCollectionLimit the limit for array and collection auto-growing
*/
public BeanPropertyBindingResult(Object target, String objectName, boolean autoGrowNestedPaths) {
public BeanPropertyBindingResult(Object target, String objectName, boolean autoGrowNestedPaths, int autoGrowCollectionLimit) {
super(objectName);
this.target = target;
this.autoGrowNestedPaths = autoGrowNestedPaths;
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
}
@@ -88,6 +92,7 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
this.beanWrapper = createBeanWrapper();
this.beanWrapper.setExtractOldValueForEditor(true);
this.beanWrapper.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
this.beanWrapper.setAutoGrowCollectionLimit(this.autoGrowCollectionLimit);
}
return this.beanWrapper;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -105,6 +105,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
/** Default object name used for binding: "target" */
public static final String DEFAULT_OBJECT_NAME = "target";
/** Default limit for array and collection growing: 256 */
public static final int DEFAULT_AUTO_GROW_COLLECTION_LIMIT = 256;
/**
* We'll create a lot of DataBinder instances: Let's use a static logger.
@@ -127,6 +130,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
private boolean autoGrowNestedPaths = true;
private int autoGrowCollectionLimit = DEFAULT_AUTO_GROW_COLLECTION_LIMIT;
private String[] allowedFields;
private String[] disallowedFields;
@@ -199,6 +204,22 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
return this.autoGrowNestedPaths;
}
/**
* Specify the limit for array and collection auto-growing.
* <p>Default is 256, preventing OutOfMemoryErrors in case of large indexes.
* Raise this limit if your auto-growing needs are unusually high.
*/
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) {
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
}
/**
* Return the current limit for array and collection auto-growing.
*/
public int getAutoGrowCollectionLimit() {
return this.autoGrowCollectionLimit;
}
/**
* Initialize standard JavaBean property access for this DataBinder.
* <p>This is the default; an explicit call just leads to eager initialization.
@@ -207,7 +228,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
public void initBeanPropertyAccess() {
Assert.state(this.bindingResult == null,
"DataBinder is already initialized - call initBeanPropertyAccess before other configuration methods");
this.bindingResult = new BeanPropertyBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths());
this.bindingResult = new BeanPropertyBindingResult(
getTarget(), getObjectName(), isAutoGrowNestedPaths(), getAutoGrowCollectionLimit());
if (this.conversionService != null) {
this.bindingResult.initConversion(this.conversionService);
}