Skip to content

Commit a1586ff

Browse files
committed
Merge branch '6.1.x'
2 parents 0637b69 + 8d05028 commit a1586ff

File tree

6 files changed

+56
-9
lines changed

6 files changed

+56
-9
lines changed

spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java

Lines changed: 8 additions & 3 deletions
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.
@@ -242,7 +242,7 @@ private static boolean isFormPost(HttpServletRequest request) {
242242
* from the body, which can fail if any other code has used the ServletRequest
243243
* to access a parameter, thus causing the input stream to be "consumed".
244244
*/
245-
private static InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException {
245+
private InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException {
246246
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
247247
Writer writer = new OutputStreamWriter(bos, FORM_CHARSET);
248248

@@ -268,7 +268,12 @@ private static InputStream getBodyFromServletRequestParameters(HttpServletReques
268268
}
269269
writer.flush();
270270

271-
return new ByteArrayInputStream(bos.toByteArray());
271+
byte[] bytes = bos.toByteArray();
272+
if (bytes.length > 0 && getHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)) {
273+
getHeaders().setContentLength(bytes.length);
274+
}
275+
276+
return new ByteArrayInputStream(bytes);
272277
}
273278

274279
}

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

Lines changed: 4 additions & 1 deletion
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/http/server/ServletServerHttpRequestTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,17 @@ void getFormBodyWhenQueryParamsAlsoPresent() throws IOException {
203203
assertThat(result).as("Invalid content returned").isEqualTo(content);
204204
}
205205

206+
@Test // gh-32471
207+
void getFormBodyWhenNotEncodedCharactersPresent() throws IOException {
208+
mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
209+
mockRequest.setMethod("POST");
210+
mockRequest.addParameter("name", "Test");
211+
mockRequest.addParameter("lastName", "Test@er");
212+
mockRequest.addHeader("Content-Length", 26);
213+
214+
byte[] result = FileCopyUtils.copyToByteArray(request.getBody());
215+
assertThat(result).isEqualTo("name=Test&lastName=Test%40er".getBytes(StandardCharsets.UTF_8));
216+
assertThat(request.getHeaders().getContentLength()).isEqualTo(result.length);
217+
}
218+
206219
}

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ class RequestParamMethodArgumentResolverTests {
7070

7171
private RequestParamMethodArgumentResolver resolver;
7272

73-
private MockHttpServletRequest request = new MockHttpServletRequest();
73+
private final MockHttpServletRequest request = new MockHttpServletRequest();
7474

7575
private NativeWebRequest webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
7676

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

7979
@BeforeEach
8080
void setup() {
@@ -186,6 +186,19 @@ void resolveStringArray() throws Exception {
186186
assertThat((String[]) result).as("Invalid result").isEqualTo(expected);
187187
}
188188

189+
@Test // gh-32577
190+
void resolveStringArrayWithEmptyArraySuffix() throws Exception {
191+
String[] expected = new String[] {"foo", "bar"};
192+
request.addParameter("name[]", expected[0]);
193+
request.addParameter("name[]", expected[1]);
194+
195+
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(String[].class);
196+
Object result = resolver.resolveArgument(param, null, webRequest, null);
197+
boolean condition = result instanceof String[];
198+
assertThat(condition).isTrue();
199+
assertThat((String[]) result).isEqualTo(expected);
200+
}
201+
189202
@Test
190203
void resolveMultipartFile() throws Exception {
191204
MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest();

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

Lines changed: 5 additions & 2 deletions
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

Lines changed: 11 additions & 1 deletion
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)