From ffd1e32dc6ba0c8731d5c09f5f9944c6eadb44e4 Mon Sep 17 00:00:00 2001 From: kssumin <201566@jnu.ac.kr> Date: Thu, 3 Apr 2025 18:56:18 +0900 Subject: [PATCH] Fix inconsistent query parameter conversion for String param Signed-off-by: kssumin <201566@jnu.ac.kr> --- .../bind/support/WebRequestDataBinder.java | 35 +++++++++++++++++-- .../support/WebRequestDataBinderTests.java | 13 +++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java index 1e393922f304..590a89dc937c 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java @@ -21,7 +21,7 @@ import jakarta.servlet.http.Part; import org.jspecify.annotations.Nullable; -import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.*; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -36,6 +36,10 @@ import org.springframework.web.multipart.MultipartRequest; import org.springframework.web.multipart.support.StandardServletPartUtils; +import java.beans.PropertyDescriptor; + +import static org.springframework.beans.BeanUtils.getPropertyDescriptor; + /** * Special {@link org.springframework.validation.DataBinder} to perform data binding * from web request parameters to JavaBeans, including support for multipart files. @@ -167,6 +171,34 @@ else if (StringUtils.startsWithIgnoreCase( doBind(mpvs); } + @Override + protected void doBind(MutablePropertyValues mpvs) { + Object target = getTarget(); + if (target == null) { + super.doBind(mpvs); + return; + } + + ConfigurablePropertyAccessor accessor = getPropertyAccessor(); + + for (PropertyValue pv : mpvs.getPropertyValues()) { + String name = pv.getName(); + Object value = pv.getValue(); + if (!name.endsWith("[]") && value instanceof String[] array && array.length > 0) { + try { + Class propertyType = accessor.getPropertyType(name); + if (propertyType == null || !propertyType.isArray()) { + mpvs.add(name, new String[] { array[0] }); + } + } + catch (InvalidPropertyException ex) { + mpvs.add(name, new String[] { array[0] }); + } + } + } + super.doBind(mpvs); + } + /** * Treats errors as fatal. *

Use this method only if it's an error if the input isn't valid. @@ -178,5 +210,4 @@ public void closeNoCatch() throws BindException { throw new BindException(getBindingResult()); } } - } diff --git a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java index cc89017f3624..466eda8a2ac1 100644 --- a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java +++ b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java @@ -40,6 +40,7 @@ /** * @author Juergen Hoeller + * @author Sumin Kim */ class WebRequestDataBinderTests { @@ -124,6 +125,18 @@ public void testFieldWithEmptyArrayIndex() { assertThat(target.getStringArray()).containsExactly("ONE", "TWO"); } + @Test + public void testFieldWithEmptyArrayIndex1() { + TestBean target = new TestBean(); + WebRequestDataBinder binder = new WebRequestDataBinder(target); + + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addParameter("touchy", "ONE"); + request.addParameter("touchy", "TWO"); + binder.bind(new ServletWebRequest(request)); + assertThat(target.getTouchy()).isEqualTo("ONE"); + } + @Test void testFieldDefault() { TestBean target = new TestBean();