Revised handling of missing data class arguments
Includes unified detection of Kotlin's optional parameters in MethodParameter.isOptional(), reduces BeanUtils.findPrimaryConstructor to Kotlin semantics (for reuse in AutowiredAnnotationBeanPostProcessor), and finally introduces a common KotlinDetector delegate with an isKotlinType(Class) check. Issue: SPR-15877 Issue: SPR-16020
This commit is contained in:
@@ -57,6 +57,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.KotlinDetector;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -762,7 +763,7 @@ public class Jackson2ObjectMapperBuilder {
|
||||
}
|
||||
|
||||
// Kotlin present?
|
||||
if (ClassUtils.isPresent("kotlin.Metadata", this.moduleClassLoader)) {
|
||||
if (KotlinDetector.isKotlinPresent()) {
|
||||
try {
|
||||
Class<? extends Module> kotlinModule = (Class<? extends Module>)
|
||||
ClassUtils.forName("com.fasterxml.jackson.module.kotlin.KotlinModule", this.moduleClassLoader);
|
||||
|
||||
@@ -198,11 +198,22 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
|
||||
WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
MethodParameter nestedParameter = parameter.nestedIfOptional();
|
||||
Class<?> type = nestedParameter.getNestedParameterType();
|
||||
Class<?> clazz = nestedParameter.getNestedParameterType();
|
||||
|
||||
Constructor<?> ctor = BeanUtils.findPrimaryConstructor(type);
|
||||
Constructor<?> ctor = BeanUtils.findPrimaryConstructor(clazz);
|
||||
if (ctor == null) {
|
||||
throw new IllegalStateException("No primary constructor found for " + type.getName());
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctors.length == 1) {
|
||||
ctor = ctors[0];
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ctor = clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("No primary or default constructor found for " + clazz, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object attribute = constructAttribute(ctor, attributeName, binderFactory, webRequest);
|
||||
@@ -263,8 +274,13 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
|
||||
}
|
||||
}
|
||||
try {
|
||||
args[i] = (value != null ?
|
||||
binder.convertIfNecessary(value, paramType, new MethodParameter(ctor, i)) : null);
|
||||
MethodParameter methodParam = new MethodParameter(ctor, i);
|
||||
if (value == null && methodParam.isOptional()) {
|
||||
args[i] = (methodParam.getParameterType() == Optional.class ? Optional.empty() : null);
|
||||
}
|
||||
else {
|
||||
args[i] = binder.convertIfNecessary(value, paramType, methodParam);
|
||||
}
|
||||
}
|
||||
catch (TypeMismatchException ex) {
|
||||
bindingFailure = true;
|
||||
|
||||
Reference in New Issue
Block a user