Browse Source

List constructor arg initialized correctly

DataBinder now uses the calculated List size rather than
the number of indexes to initialize the list.

Closes gh-34145
pull/34398/head
rstoyanchev 12 months ago
parent
commit
4350fc21b3
  1. 4
      spring-context/src/main/java/org/springframework/validation/DataBinder.java
  2. 18
      spring-context/src/test/java/org/springframework/validation/DataBinderConstructTests.java

4
spring-context/src/main/java/org/springframework/validation/DataBinder.java

@ -1060,7 +1060,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
} }
int size = (indexes.last() < this.autoGrowCollectionLimit ? indexes.last() + 1 : 0); int size = (indexes.last() < this.autoGrowCollectionLimit ? indexes.last() + 1 : 0);
List<V> list = (List<V>) CollectionFactory.createCollection(paramType, size); List<V> list = (List<V>) CollectionFactory.createCollection(paramType, size);
indexes.forEach(i -> list.add(null)); for (int i = 0; i < size; i++) {
list.add(null);
}
for (int index : indexes) { for (int index : indexes) {
list.set(index, (V) createObject(elementType, paramPath + "[" + index + "].", valueResolver)); list.set(index, (V) createObject(elementType, paramPath + "[" + index + "].", valueResolver));
} }

18
spring-context/src/test/java/org/springframework/validation/DataBinderConstructTests.java

@ -121,6 +121,24 @@ class DataBinderConstructTests {
assertThat(list.get(2).param1()).isEqualTo("value3"); assertThat(list.get(2).param1()).isEqualTo("value3");
} }
@Test // gh-34145
void listBindingWithNonconsecutiveIndices() {
MapValueResolver valueResolver = new MapValueResolver(Map.of(
"dataClassList[0].param1", "value1", "dataClassList[0].param2", "true",
"dataClassList[1].param1", "value2", "dataClassList[1].param2", "true",
"dataClassList[3].param1", "value3", "dataClassList[3].param2", "true"));
DataBinder binder = initDataBinder(ListDataClass.class);
binder.construct(valueResolver);
ListDataClass dataClass = getTarget(binder);
List<DataClass> list = dataClass.dataClassList();
assertThat(list.get(0).param1()).isEqualTo("value1");
assertThat(list.get(1).param1()).isEqualTo("value2");
assertThat(list.get(3).param1()).isEqualTo("value3");
}
@Test @Test
void mapBinding() { void mapBinding() {
MapValueResolver valueResolver = new MapValueResolver(Map.of( MapValueResolver valueResolver = new MapValueResolver(Map.of(

Loading…
Cancel
Save