Skip to content

Commit a5518df

Browse files
committed
Fix handling of primitive boolean @RequestParam with required=false
Signed-off-by: Aman Gautam <amangautam2128@gmail.com>
1 parent baca3a0 commit a5518df

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ public AbstractNamedValueMethodArgumentResolver(@Nullable ConfigurableBeanFactor
115115
}
116116

117117
Object arg = resolveName(resolvedName.toString(), nestedParameter, webRequest);
118+
boolean valueMissing =
119+
(resolveName(resolvedName.toString(), nestedParameter, webRequest) == null);
118120
if (arg == null) {
119121
if (namedValueInfo.defaultValue != null) {
120122
arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
@@ -130,20 +132,32 @@ else if ("".equals(arg) && namedValueInfo.defaultValue != null) {
130132
arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
131133
}
132134

133-
if (binderFactory != null && (arg != null || !hasDefaultValue)) {
135+
136+
boolean skipConversion =
137+
valueMissing &&
138+
parameter.getParameterType().isPrimitive() &&
139+
!namedValueInfo.required &&
140+
!hasDefaultValue;
141+
142+
143+
144+
if (binderFactory != null && !skipConversion && (arg != null || !hasDefaultValue)) {
134145
arg = convertIfNecessary(parameter, webRequest, binderFactory, namedValueInfo, arg);
135-
// Check for null value after conversion of incoming argument value
136146
if (arg == null) {
137147
if (namedValueInfo.defaultValue != null) {
138148
arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
139-
arg = convertIfNecessary(parameter, webRequest, binderFactory, namedValueInfo, arg);
140149
}
141150
else if (namedValueInfo.required && !nestedParameter.isOptional()) {
142-
handleMissingValueAfterConversion(resolvedName.toString(), nestedParameter, webRequest);
151+
handleMissingValue(resolvedName.toString(), nestedParameter, webRequest);
152+
}
153+
else if (parameter.getParameterType().isPrimitive()) {
154+
arg = handleNullValue(resolvedName.toString(), null, parameter.getParameterType());
143155
}
144156
}
157+
145158
}
146159

160+
147161
handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);
148162

149163
return arg;

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,23 @@ void modelAttributeAdvice() throws Exception {
256256
assertThat(mav.getModel().get("attr2")).isEqualTo("gAttr2");
257257
}
258258

259+
@Test
260+
void primitiveBooleanRequiredFalseShouldNotThrowTypeMismatch() throws Exception {
261+
this.handlerAdapter.afterPropertiesSet();
262+
263+
this.request.setRequestURI("/test");
264+
265+
HandlerMethod handlerMethod =
266+
handlerMethod(new PrimitiveBooleanController(), "test", boolean.class);
267+
268+
this.handlerAdapter.handle(this.request, this.response, handlerMethod);
269+
270+
assertThat(this.response.getContentAsString()).isEqualTo("false");
271+
}
272+
273+
274+
275+
259276
@Test
260277
void prototypeControllerAdvice() throws Exception {
261278
this.webAppContext.registerPrototype("maa", ModelAttributeAdvice.class);
@@ -440,6 +457,17 @@ void test(@RequestParam boolean bool) {
440457
}
441458
}
442459

460+
@RestController
461+
static class PrimitiveBooleanController {
462+
463+
@GetMapping("/test")
464+
public String test(@RequestParam(required = false) boolean flag) {
465+
return String.valueOf(flag);
466+
}
467+
}
468+
469+
470+
443471

444472

445473
@ControllerAdvice

0 commit comments

Comments
 (0)