Skip to content

Commit fee8abf

Browse files
committed
Drop "[]" from parameter names in data binding
Closes gh-25836
1 parent d05803a commit fee8abf

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -194,6 +194,7 @@ public boolean isBindEmptyMultipartFiles() {
194194
protected void doBind(MutablePropertyValues mpvs) {
195195
checkFieldDefaults(mpvs);
196196
checkFieldMarkers(mpvs);
197+
adaptEmptyArrayIndices(mpvs);
197198
super.doBind(mpvs);
198199
}
199200

@@ -249,6 +250,27 @@ protected void checkFieldMarkers(MutablePropertyValues mpvs) {
249250
}
250251
}
251252

253+
/**
254+
* Check for property values with names that end on {@code "[]"}. This is
255+
* used by some clients for array syntax without an explicit index value.
256+
* If such values are found, drop the brackets to adapt to the expected way
257+
* of expressing the same for data binding purposes.
258+
* @param mpvs the property values to be bound (can be modified)
259+
* @since 5.3
260+
*/
261+
protected void adaptEmptyArrayIndices(MutablePropertyValues mpvs) {
262+
for (PropertyValue pv : mpvs.getPropertyValues()) {
263+
String name = pv.getName();
264+
if (name.endsWith("[]")) {
265+
String field = name.substring(0, name.length() - 2);
266+
if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) {
267+
mpvs.add(field, pv.getValue());
268+
}
269+
mpvs.removePropertyValue(pv);
270+
}
271+
}
272+
}
273+
252274
/**
253275
* Determine an empty value for the specified field.
254276
* <p>The default implementation delegates to {@link #getEmptyValue(Class)}

spring-web/src/test/java/org/springframework/web/bind/support/WebExchangeDataBinderTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -104,6 +104,15 @@ public void testFieldPrefixCausesFieldResetWithIgnoreUnknownFields() throws Exce
104104
assertThat(this.testBean.isPostProcessed()).isFalse();
105105
}
106106

107+
@Test // gh-25836
108+
public void testFieldWithEmptyArrayIndex() {
109+
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
110+
formData.add("stringArray[]", "ONE");
111+
formData.add("stringArray[]", "TWO");
112+
this.binder.bind(exchange(formData)).block(Duration.ofMillis(5000));
113+
assertThat(this.testBean.getStringArray()).containsExactly("ONE", "TWO");
114+
}
115+
107116
@Test
108117
public void testFieldDefault() throws Exception {
109118
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();

spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -112,6 +112,18 @@ public void testFieldPrefixCausesFieldResetWithIgnoreUnknownFields() throws Exce
112112
assertThat(target.isPostProcessed()).isFalse();
113113
}
114114

115+
@Test // gh-25836
116+
public void testFieldWithEmptyArrayIndex() {
117+
TestBean target = new TestBean();
118+
WebRequestDataBinder binder = new WebRequestDataBinder(target);
119+
120+
MockHttpServletRequest request = new MockHttpServletRequest();
121+
request.addParameter("stringArray[]", "ONE");
122+
request.addParameter("stringArray[]", "TWO");
123+
binder.bind(new ServletWebRequest(request));
124+
assertThat(target.getStringArray()).containsExactly("ONE", "TWO");
125+
}
126+
115127
@Test
116128
public void testFieldDefault() throws Exception {
117129
TestBean target = new TestBean();

0 commit comments

Comments
 (0)