Browse Source

Drop "[]" from parameter names in data binding

Closes gh-25836
pull/25899/head
Rossen Stoyanchev 5 years ago
parent
commit
fee8abfa5f
  1. 24
      spring-web/src/main/java/org/springframework/web/bind/WebDataBinder.java
  2. 11
      spring-web/src/test/java/org/springframework/web/bind/support/WebExchangeDataBinderTests.java
  3. 14
      spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -194,6 +194,7 @@ public class WebDataBinder extends DataBinder { @@ -194,6 +194,7 @@ public class WebDataBinder extends DataBinder {
protected void doBind(MutablePropertyValues mpvs) {
checkFieldDefaults(mpvs);
checkFieldMarkers(mpvs);
adaptEmptyArrayIndices(mpvs);
super.doBind(mpvs);
}
@ -249,6 +250,27 @@ public class WebDataBinder extends DataBinder { @@ -249,6 +250,27 @@ public class WebDataBinder extends DataBinder {
}
}
/**
* Check for property values with names that end on {@code "[]"}. This is
* used by some clients for array syntax without an explicit index value.
* If such values are found, drop the brackets to adapt to the expected way
* of expressing the same for data binding purposes.
* @param mpvs the property values to be bound (can be modified)
* @since 5.3
*/
protected void adaptEmptyArrayIndices(MutablePropertyValues mpvs) {
for (PropertyValue pv : mpvs.getPropertyValues()) {
String name = pv.getName();
if (name.endsWith("[]")) {
String field = name.substring(0, name.length() - 2);
if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) {
mpvs.add(field, pv.getValue());
}
mpvs.removePropertyValue(pv);
}
}
}
/**
* Determine an empty value for the specified field.
* <p>The default implementation delegates to {@link #getEmptyValue(Class)}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -104,6 +104,15 @@ public class WebExchangeDataBinderTests { @@ -104,6 +104,15 @@ public class WebExchangeDataBinderTests {
assertThat(this.testBean.isPostProcessed()).isFalse();
}
@Test // gh-25836
public void testFieldWithEmptyArrayIndex() {
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("stringArray[]", "ONE");
formData.add("stringArray[]", "TWO");
this.binder.bind(exchange(formData)).block(Duration.ofMillis(5000));
assertThat(this.testBean.getStringArray()).containsExactly("ONE", "TWO");
}
@Test
public void testFieldDefault() throws Exception {
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -112,6 +112,18 @@ public class WebRequestDataBinderTests { @@ -112,6 +112,18 @@ public class WebRequestDataBinderTests {
assertThat(target.isPostProcessed()).isFalse();
}
@Test // gh-25836
public void testFieldWithEmptyArrayIndex() {
TestBean target = new TestBean();
WebRequestDataBinder binder = new WebRequestDataBinder(target);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("stringArray[]", "ONE");
request.addParameter("stringArray[]", "TWO");
binder.bind(new ServletWebRequest(request));
assertThat(target.getStringArray()).containsExactly("ONE", "TWO");
}
@Test
public void testFieldDefault() throws Exception {
TestBean target = new TestBean();

Loading…
Cancel
Save