Support single-value request param resolution for data class constructors

Prior to this commit, when Web MVC attempted to resolve a constructor
argument for a data class constructor with @ModelAttribute binding,
ModelAttributeMethodProcessor failed to unwrap the array returned by
WebRequest.getParameter(String).

According to the Javadoc for WebRequest.getParameter(String), "a
single-value parameter will be exposed as an array with a single
element."

This commit fixes this issue by extracting the single value from such
an array and using that as the constructor argument (potentially
converted by the WebDataBinder).

Closes gh-25200
This commit is contained in:
Vlad Kisel
2020-06-07 00:11:34 +02:00
committed by Sam Brannen
parent c20a43f72b
commit 9ddab9e69b
2 changed files with 47 additions and 3 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.web.method.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -75,6 +76,7 @@ import org.springframework.web.multipart.support.StandardServletPartUtils;
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @author Vladislav Kisel
* @since 3.1
*/
public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {
@@ -268,6 +270,12 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
}
}
}
// Singular web parameters are wrapped with array, extract it so it can be picked up by conversion service later on
if (value != null && value.getClass().isArray() && Array.getLength(value) == 1) {
value = Array.get(value, 0);
}
try {
MethodParameter methodParam = new FieldAwareConstructorParameter(ctor, i, paramName);
if (value == null && methodParam.isOptional()) {