diff --git a/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java b/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java index ec660bf713c..132ba8bd2d2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java +++ b/spring-boot/src/main/java/org/springframework/boot/bind/PropertySourcesPropertyValues.java @@ -43,7 +43,8 @@ import org.springframework.validation.DataBinder; */ public class PropertySourcesPropertyValues implements PropertyValues { - private static final Pattern COLLECTION_PROPERTY = Pattern.compile("\\[(\\d+)\\]"); + private static final Pattern COLLECTION_PROPERTY = Pattern + .compile("\\[(\\d+)\\](\\.\\S+)?"); private final PropertySources propertySources; diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java index 9cbac1d4ff8..c84e12115b9 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/PropertySourcesPropertyValuesTests.java @@ -40,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Dave Syer * @author Phillip Webb + * @author Stephane Nicoll */ public class PropertySourcesPropertyValuesTests { @@ -222,10 +223,33 @@ public class PropertySourcesPropertyValuesTests { assertThat(target.getList()).containsExactly("f0"); } + @Test + public void testFirstCollectionPropertyWinsNestedAttributes() throws Exception { + ListTestBean target = new ListTestBean(); + DataBinder binder = new DataBinder(target); + Map first = new LinkedHashMap(); + first.put("list[0].description", "another description"); + Map second = new LinkedHashMap(); + second.put("list[0].name", "first name"); + second.put("list[0].description", "first description"); + second.put("list[1].name", "second name"); + second.put("list[1].description", "second description"); + this.propertySources.addFirst(new MapPropertySource("s", second)); + this.propertySources.addFirst(new MapPropertySource("f", first)); + binder.bind(new PropertySourcesPropertyValues(this.propertySources)); + target.getList(); + assertThat(target.getList()).hasSize(1); + assertThat(target.getList().get(0).getDescription()) + .isEqualTo("another description"); + assertThat(target.getList().get(0).getName()).isNull(); + } + public static class TestBean { private String name; + private String description; + public String getName() { return this.name; } @@ -233,6 +257,15 @@ public class PropertySourcesPropertyValuesTests { public void setName(String name) { this.name = name; } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + } public static class FooBean { @@ -260,6 +293,21 @@ public class PropertySourcesPropertyValuesTests { public void setList(List list) { this.list = list; } + + } + + public static class ListTestBean { + + private List list = new ArrayList(); + + public List getList() { + return this.list; + } + + public void setList(List list) { + this.list = list; + } + } }