diff --git a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedDataBinder.java b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedDataBinder.java index 37c003c3916..b9c7bb4d6c8 100644 --- a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedDataBinder.java +++ b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedDataBinder.java @@ -18,6 +18,7 @@ package org.springframework.boot.bind; import java.net.InetAddress; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -232,11 +233,19 @@ public class RelaxedDataBinder extends DataBinder { && !descriptor.getType().equals(Object.class)) { return; } + String extensionName = path.prefix(index + 1); + if (wrapper.isReadableProperty(extensionName)) { + Object currentValue = wrapper.getPropertyValue(extensionName); + if ((descriptor.isCollection() && currentValue instanceof Collection) + || (!descriptor.isCollection() && currentValue instanceof Map)) { + return; + } + } Object extend = new LinkedHashMap(); if (descriptor.isCollection()) { extend = new ArrayList(); } - wrapper.setPropertyValue(path.prefix(index + 1), extend); + wrapper.setPropertyValue(extensionName, extend); } private String getActualPropertyName(BeanWrapper target, String prefix, String name) { diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java index 53fa1880115..138bcef223c 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java @@ -380,6 +380,22 @@ public class RelaxedDataBinderTests { assertEquals("123", map.get("value")); } + @SuppressWarnings("unchecked") + @Test + public void testBindOverlappingNestedMaps() throws Exception { + Map target = new LinkedHashMap(); + BindingResult result = bind(target, "a.b.c.d: abc\na.b.c1.d1: efg"); + assertEquals(0, result.getErrorCount()); + + Map a = (Map) target.get("a"); + Map b = (Map) a.get("b"); + Map c = (Map) b.get("c"); + assertEquals("abc", c.get("d")); + + Map c1 = (Map) b.get("c1"); + assertEquals("efg", c1.get("d1")); + } + private BindingResult bind(Object target, String values) throws Exception { return bind(target, values, null); }