Browse Source

Apply default value in case of null after conversion

Closes gh-29550
pull/30709/head
rstoyanchev 1 year ago
parent
commit
b98c1ec36a
  1. 8
      spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/AbstractNamedValueMethodArgumentResolver.java
  2. 8
      spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/AbstractNamedValueMethodArgumentResolver.java
  3. 8
      spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java
  4. 15
      spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java

8
spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/AbstractNamedValueMethodArgumentResolver.java

@ -108,11 +108,15 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements SyncHa
if (parameter != nestedParameter || !ClassUtils.isAssignableValue(parameter.getParameterType(), arg)) { if (parameter != nestedParameter || !ClassUtils.isAssignableValue(parameter.getParameterType(), arg)) {
arg = this.conversionService.convert(arg, TypeDescriptor.forObject(arg), new TypeDescriptor(parameter)); arg = this.conversionService.convert(arg, TypeDescriptor.forObject(arg), new TypeDescriptor(parameter));
// Check for null value after conversion of incoming argument value // Check for null value after conversion of incoming argument value
if (arg == null && namedValueInfo.defaultValue == null && if (arg == null) {
namedValueInfo.required && !nestedParameter.isOptional()) { if (namedValueInfo.defaultValue != null) {
arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
}
else if (namedValueInfo.required && !nestedParameter.isOptional()) {
handleMissingValue(namedValueInfo.name, nestedParameter, message); handleMissingValue(namedValueInfo.name, nestedParameter, message);
} }
} }
}
return arg; return arg;
} }

8
spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/AbstractNamedValueMethodArgumentResolver.java

@ -116,11 +116,15 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
if (parameter != nestedParameter || !ClassUtils.isAssignableValue(parameter.getParameterType(), arg)) { if (parameter != nestedParameter || !ClassUtils.isAssignableValue(parameter.getParameterType(), arg)) {
arg = this.conversionService.convert(arg, TypeDescriptor.forObject(arg), new TypeDescriptor(parameter)); arg = this.conversionService.convert(arg, TypeDescriptor.forObject(arg), new TypeDescriptor(parameter));
// Check for null value after conversion of incoming argument value // Check for null value after conversion of incoming argument value
if (arg == null && namedValueInfo.defaultValue == null && if (arg == null) {
namedValueInfo.required && !nestedParameter.isOptional()) { if (namedValueInfo.defaultValue != null) {
arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
}
else if (namedValueInfo.required && !nestedParameter.isOptional()) {
handleMissingValue(namedValueInfo.name, nestedParameter, message); handleMissingValue(namedValueInfo.name, nestedParameter, message);
} }
} }
}
handleResolvedValue(arg, namedValueInfo.name, parameter, message); handleResolvedValue(arg, namedValueInfo.name, parameter, message);

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

@ -133,11 +133,15 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
namedValueInfo.name, parameter, ex.getCause()); namedValueInfo.name, parameter, ex.getCause());
} }
// Check for null value after conversion of incoming argument value // Check for null value after conversion of incoming argument value
if (arg == null && namedValueInfo.defaultValue == null && if (arg == null) {
namedValueInfo.required && !nestedParameter.isOptional()) { if (namedValueInfo.defaultValue != null) {
arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
}
else if (namedValueInfo.required && !nestedParameter.isOptional()) {
handleMissingValueAfterConversion(namedValueInfo.name, nestedParameter, webRequest); handleMissingValueAfterConversion(namedValueInfo.name, nestedParameter, webRequest);
} }
} }
}
handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest); handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);

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

@ -462,6 +462,21 @@ public class RequestParamMethodArgumentResolverTests {
assertThat(arg).isNull(); assertThat(arg).isNull();
} }
@Test // gh-29550
public void missingRequestParamEmptyValueNotRequiredWithDefaultValue() throws Exception {
WebDataBinder binder = new WebRequestDataBinder(null);
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
WebDataBinderFactory binderFactory = mock();
given(binderFactory.createBinder(webRequest, null, "name")).willReturn(binder);
request.addParameter("name", " ");
MethodParameter param = this.testMethod.annot(requestParam().notRequired("bar")).arg(String.class);
Object arg = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertThat(arg).isEqualTo("bar");
}
@Test @Test
public void resolveSimpleTypeParam() throws Exception { public void resolveSimpleTypeParam() throws Exception {
request.setParameter("stringNotAnnot", "plainValue"); request.setParameter("stringNotAnnot", "plainValue");

Loading…
Cancel
Save