DataBinder unwraps Optional objects and allows for proper handling of Optional.empty()
Issue: SPR-12241
This commit is contained in:
@@ -24,6 +24,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -41,7 +42,9 @@ import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -119,6 +122,19 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
*/
|
||||
protected static final Log logger = LogFactory.getLog(DataBinder.class);
|
||||
|
||||
private static Class<?> javaUtilOptionalClass = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
javaUtilOptionalClass =
|
||||
ClassUtils.forName("java.util.Optional", DataBinder.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Java 8 not available - Optional references simply not supported then.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Object target;
|
||||
|
||||
private final String objectName;
|
||||
@@ -165,7 +181,12 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
* @param objectName the name of the target object
|
||||
*/
|
||||
public DataBinder(Object target, String objectName) {
|
||||
this.target = target;
|
||||
if (target != null && target.getClass().equals(javaUtilOptionalClass)) {
|
||||
this.target = OptionalUnwrapper.unwrap(target);
|
||||
}
|
||||
else {
|
||||
this.target = target;
|
||||
}
|
||||
this.objectName = objectName;
|
||||
}
|
||||
|
||||
@@ -779,4 +800,22 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
return getBindingResult().getModel();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on Java 8.
|
||||
*/
|
||||
@UsesJava8
|
||||
private static class OptionalUnwrapper {
|
||||
|
||||
public static Object unwrap(Object optionalObject) {
|
||||
Optional<?> optional = (Optional<?>) optionalObject;
|
||||
if (!optional.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
Object result = optional.get();
|
||||
Assert.isTrue(!(result instanceof Optional), "Multi-level Optional usage not supported");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user