Skip to content

Commit bcd8896

Browse files
committed
Polish contribution
See gh-25200
1 parent 53b8d73 commit bcd8896

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java

Lines changed: 10 additions & 6 deletions
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-2021 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.
@@ -40,6 +40,7 @@
4040
import org.springframework.core.annotation.AnnotationUtils;
4141
import org.springframework.lang.Nullable;
4242
import org.springframework.util.Assert;
43+
import org.springframework.util.ObjectUtils;
4344
import org.springframework.validation.BindException;
4445
import org.springframework.validation.BindingResult;
4546
import org.springframework.validation.Errors;
@@ -277,6 +278,14 @@ protected Object constructAttribute(Constructor<?> ctor, String attributeName, M
277278
String paramName = paramNames[i];
278279
Class<?> paramType = paramTypes[i];
279280
Object value = webRequest.getParameterValues(paramName);
281+
282+
// Since WebRequest#getParameter exposes a single-value parameter as an array
283+
// with a single element, we unwrap the single value in such cases, analogous
284+
// to WebExchangeDataBinder.addBindValue(Map<String, Object>, String, List<?>).
285+
if (ObjectUtils.isArray(value) && Array.getLength(value) == 1) {
286+
value = Array.get(value, 0);
287+
}
288+
280289
if (value == null) {
281290
if (fieldDefaultPrefix != null) {
282291
value = webRequest.getParameter(fieldDefaultPrefix + paramName);
@@ -288,11 +297,6 @@ protected Object constructAttribute(Constructor<?> ctor, String attributeName, M
288297
}
289298
}
290299

291-
// Singular web parameters are wrapped with array, extract it so it can be picked up by conversion service later on
292-
if (value != null && value.getClass().isArray() && Array.getLength(value) == 1) {
293-
value = Array.get(value, 0);
294-
}
295-
296300
try {
297301
MethodParameter methodParam = new FieldAwareConstructorParameter(ctor, i, paramName);
298302
if (value == null && methodParam.isOptional()) {

spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 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.
@@ -19,7 +19,6 @@
1919
import java.lang.annotation.Retention;
2020
import java.lang.annotation.Target;
2121
import java.lang.reflect.Method;
22-
import java.util.Arrays;
2322
import java.util.List;
2423

2524
import org.junit.jupiter.api.BeforeEach;
@@ -271,7 +270,7 @@ public void handleNotAnnotatedReturnValue() throws Exception {
271270
}
272271

273272
@Test // gh-25182
274-
public void testResolveConstructorListParameter() throws Exception {
273+
public void resolveConstructorListArgumentFromCommaSeparatedRequestParameter() throws Exception {
275274
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
276275
mockRequest.addParameter("listOfStrings", "1,2");
277276
ServletWebRequest requestWithParam = new ServletWebRequest(mockRequest);
@@ -281,14 +280,14 @@ public void testResolveConstructorListParameter() throws Exception {
281280
.willAnswer(invocation -> {
282281
WebRequestDataBinder binder = new WebRequestDataBinder(invocation.getArgument(1));
283282

284-
// Add conversion service which will convert "1,2" to List of size 2
283+
// Add conversion service which will convert "1,2" to a list
285284
binder.setConversionService(new DefaultFormattingConversionService());
286285
return binder;
287286
});
288287

289288
Object resolved = this.processor.resolveArgument(this.beanWithConstructorArgs, this.container, requestWithParam, factory);
290-
assertThat(resolved).isNotNull();
291-
assertThat(((TestBeanWithConstructorArgs) resolved).listOfStrings).isEqualTo(Arrays.asList("1", "2"));
289+
assertThat(resolved).isInstanceOf(TestBeanWithConstructorArgs.class);
290+
assertThat(((TestBeanWithConstructorArgs) resolved).listOfStrings).containsExactly("1", "2");
292291
}
293292

294293
private void testGetAttributeFromModel(String expectedAttrName, MethodParameter param) throws Exception {

0 commit comments

Comments
 (0)