Guard against binding non-instantiable types
Update `JavaBeanBinder` so that null instances that are non-instantiable are not bound. Fixes gh-10131
This commit is contained in:
parent
b7c37c2807
commit
3ec3b64d45
|
|
@ -168,17 +168,17 @@ class JavaBeanBinder implements BeanBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> Bean<T> get(Bindable<T> bindable,
|
public static <T> Bean<T> get(Bindable<T> bindable, boolean canCallGetValue) {
|
||||||
boolean useExistingValueForType) {
|
|
||||||
Class<?> type = bindable.getType().resolve();
|
Class<?> type = bindable.getType().resolve();
|
||||||
Supplier<T> value = bindable.getValue();
|
Supplier<T> value = bindable.getValue();
|
||||||
if (value == null && !isInstantiable(type)) {
|
T instance = null;
|
||||||
return null;
|
if (canCallGetValue && value != null) {
|
||||||
}
|
instance = value.get();
|
||||||
if (useExistingValueForType && value != null) {
|
|
||||||
T instance = value.get();
|
|
||||||
type = (instance != null ? instance.getClass() : type);
|
type = (instance != null ? instance.getClass() : type);
|
||||||
}
|
}
|
||||||
|
if (instance == null && !isInstantiable(type)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Bean<?> bean = Bean.cached;
|
Bean<?> bean = Bean.cached;
|
||||||
if (bean == null || !type.equals(bean.getType())) {
|
if (bean == null || !type.equals(bean.getType())) {
|
||||||
bean = new Bean<>(type);
|
bean = new Bean<>(type);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.validation.Validation;
|
||||||
|
|
||||||
import org.assertj.core.matcher.AssertionMatcher;
|
import org.assertj.core.matcher.AssertionMatcher;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
|
|
@ -30,14 +32,21 @@ import org.junit.rules.ExpectedException;
|
||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.bind.validation.ValidationBindHandler;
|
||||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||||
|
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||||
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
|
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.convert.ConversionFailedException;
|
import org.springframework.core.convert.ConversionFailedException;
|
||||||
|
import org.springframework.core.env.PropertySource;
|
||||||
import org.springframework.core.env.StandardEnvironment;
|
import org.springframework.core.env.StandardEnvironment;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
|
@ -239,6 +248,20 @@ public class BinderTests {
|
||||||
this.binder.bind("foo", target);
|
this.binder.bind("foo", target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindToValidatedBeanWithResourceAndNonEnumerablePropertySource() {
|
||||||
|
ConfigurationPropertySources.from(new PropertySource<String>("test") {
|
||||||
|
@Override
|
||||||
|
public Object getProperty(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).forEach(this.sources::add);
|
||||||
|
Validator validator = new SpringValidatorAdapter(Validation.byDefaultProvider()
|
||||||
|
.configure().buildValidatorFactory().getValidator());
|
||||||
|
this.binder.bind("foo", Bindable.of(ResourceBean.class),
|
||||||
|
new ValidationBindHandler(validator));
|
||||||
|
}
|
||||||
|
|
||||||
public static class JavaBean {
|
public static class JavaBean {
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|
@ -265,4 +288,19 @@ public class BinderTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Validated
|
||||||
|
public static class ResourceBean {
|
||||||
|
|
||||||
|
private Resource resource;
|
||||||
|
|
||||||
|
public Resource getResource() {
|
||||||
|
return this.resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResource(Resource resource) {
|
||||||
|
this.resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue