Skip to content

Commit c09e711

Browse files
committed
Unwrap Optional for @RequestParam reverse resolution
Closes gh-22656
1 parent 4e63153 commit c09e711

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

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

Lines changed: 7 additions & 1 deletion
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-2019 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.
@@ -20,6 +20,7 @@
2020
import java.util.Collection;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Optional;
2324
import javax.servlet.http.HttpServletRequest;
2425
import javax.servlet.http.Part;
2526

@@ -217,6 +218,11 @@ public void contributeMethodArgument(MethodParameter parameter, @Nullable Object
217218
parameter.getParameterName() : requestParam.name());
218219
Assert.state(name != null, "Unresolvable parameter name");
219220

221+
parameter = parameter.nestedIfOptional();
222+
if (value instanceof Optional) {
223+
value = ((Optional<?>) value).orElse(null);
224+
}
225+
220226
if (value == null) {
221227
if (requestParam != null &&
222228
(!requestParam.required() || !requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE))) {

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2018 the original author or authors.
2+
* Copyright 2012-2019 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.
@@ -23,6 +23,7 @@
2323
import java.lang.annotation.Target;
2424
import java.util.Arrays;
2525
import java.util.List;
26+
import java.util.Optional;
2627
import javax.servlet.http.HttpServletRequest;
2728

2829
import org.hamcrest.Matchers;
@@ -264,6 +265,15 @@ public void fromMethodNameWithOptionalParam() {
264265
assertThat(uriComponents.toUriString(), is("http://localhost/something/optional-param"));
265266
}
266267

268+
@Test // gh-22656
269+
public void fromMethodNameWithOptionalNamedParam() {
270+
UriComponents uriComponents = fromMethodName(ControllerWithMethods.class,
271+
"methodWithOptionalNamedParam", Optional.of("foo")).build();
272+
273+
assertThat(uriComponents.toUriString(),
274+
is("http://localhost/something/optional-param-with-name?search=foo"));
275+
}
276+
267277
@Test
268278
public void fromMethodNameWithMetaAnnotation() {
269279
UriComponents uriComponents = fromMethodName(MetaAnnotationController.class, "handleInput").build();
@@ -533,6 +543,11 @@ HttpEntity<Void> methodWithMultiValueRequestParams(@PathVariable String id,
533543
HttpEntity<Void> methodWithOptionalParam(@RequestParam(defaultValue = "") String q) {
534544
return null;
535545
}
546+
547+
@GetMapping("/optional-param-with-name")
548+
HttpEntity<Void> methodWithOptionalNamedParam(@RequestParam("search") Optional<String> q) {
549+
return null;
550+
}
536551
}
537552

538553

0 commit comments

Comments
 (0)