Apply default value in case of null after conversion

Closes gh-29550
This commit is contained in:
rstoyanchev 2023-06-20 13:01:37 +01:00
parent 37ff9792be
commit b98c1ec36a
4 changed files with 36 additions and 9 deletions

View File

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

View File

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

View File

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

View File

@ -462,6 +462,21 @@ public class RequestParamMethodArgumentResolverTests {
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
public void resolveSimpleTypeParam() throws Exception {
request.setParameter("stringNotAnnot", "plainValue");