Skip to content

Commit 8d05028

Browse files
committed
RequestParam resolver supports empty array suffix
Closes gh-32577
1 parent 4a68c44 commit 8d05028

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -179,6 +179,9 @@ protected Object resolveName(String name, MethodParameter parameter, NativeWebRe
179179
}
180180
if (arg == null) {
181181
String[] paramValues = request.getParameterValues(name);
182+
if (paramValues == null) {
183+
paramValues = request.getParameterValues(name + "[]");
184+
}
182185
if (paramValues != null) {
183186
arg = (paramValues.length == 1 ? paramValues[0] : paramValues);
184187
}

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

+15-2
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ class RequestParamMethodArgumentResolverTests {
6666

6767
private RequestParamMethodArgumentResolver resolver = new RequestParamMethodArgumentResolver(null, true);
6868

69-
private MockHttpServletRequest request = new MockHttpServletRequest();
69+
private final MockHttpServletRequest request = new MockHttpServletRequest();
7070

7171
private NativeWebRequest webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
7272

73-
private ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build();
73+
private final ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build();
7474

7575

7676
@Test
@@ -167,6 +167,19 @@ void resolveStringArray() throws Exception {
167167
assertThat((String[]) result).as("Invalid result").isEqualTo(expected);
168168
}
169169

170+
@Test // gh-32577
171+
void resolveStringArrayWithEmptyArraySuffix() throws Exception {
172+
String[] expected = new String[] {"foo", "bar"};
173+
request.addParameter("name[]", expected[0]);
174+
request.addParameter("name[]", expected[1]);
175+
176+
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(String[].class);
177+
Object result = resolver.resolveArgument(param, null, webRequest, null);
178+
boolean condition = result instanceof String[];
179+
assertThat(condition).isTrue();
180+
assertThat((String[]) result).isEqualTo(expected);
181+
}
182+
170183
@Test
171184
void resolveMultipartFile() throws Exception {
172185
MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest();

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestParamMethodArgumentResolver.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -100,8 +100,11 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
100100
@Override
101101
@Nullable
102102
protected Object resolveNamedValue(String name, MethodParameter parameter, ServerWebExchange exchange) {
103-
List<String> paramValues = exchange.getRequest().getQueryParams().get(name);
104103
Object result = null;
104+
List<String> paramValues = exchange.getRequest().getQueryParams().get(name);
105+
if (paramValues == null) {
106+
paramValues = exchange.getRequest().getQueryParams().get(name + "[]");
107+
}
105108
if (paramValues != null) {
106109
result = (paramValues.size() == 1 ? paramValues.get(0) : paramValues);
107110
}

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestParamMethodArgumentResolverTests.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class RequestParamMethodArgumentResolverTests {
5353

5454
private BindingContext bindContext;
5555

56-
private ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build();
56+
private final ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build();
5757

5858

5959
@BeforeEach
@@ -130,6 +130,16 @@ void resolveStringArray() {
130130
assertThat((String[]) result).isEqualTo(new String[] {"foo", "bar"});
131131
}
132132

133+
@Test // gh-32577
134+
void resolveStringArrayWithEmptyArraySuffix() {
135+
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(String[].class);
136+
MockServerHttpRequest request = MockServerHttpRequest.get("/path?name[]=foo&name[]=bar").build();
137+
Object result = resolve(param, MockServerWebExchange.from(request));
138+
boolean condition = result instanceof String[];
139+
assertThat(condition).isTrue();
140+
assertThat((String[]) result).isEqualTo(new String[] {"foo", "bar"});
141+
}
142+
133143
@Test
134144
void resolveDefaultValue() {
135145
MethodParameter param = this.testMethod.annot(requestParam().notRequired("bar")).arg(String.class);

0 commit comments

Comments
 (0)