commit
c4432a81a8
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.springframework.beans.NotReadablePropertyException;
|
||||||
import org.springframework.boot.context.properties.bind.AbstractBindHandler;
|
import org.springframework.boot.context.properties.bind.AbstractBindHandler;
|
||||||
import org.springframework.boot.context.properties.bind.BindContext;
|
import org.springframework.boot.context.properties.bind.BindContext;
|
||||||
import org.springframework.boot.context.properties.bind.BindHandler;
|
import org.springframework.boot.context.properties.bind.BindHandler;
|
||||||
|
|
@ -33,6 +34,7 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyN
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.validation.AbstractBindingResult;
|
import org.springframework.validation.AbstractBindingResult;
|
||||||
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -143,14 +145,14 @@ public class ValidationBindHandler extends AbstractBindHandler {
|
||||||
/**
|
/**
|
||||||
* {@link AbstractBindingResult} implementation backed by the bound properties.
|
* {@link AbstractBindingResult} implementation backed by the bound properties.
|
||||||
*/
|
*/
|
||||||
private class ValidationResult extends AbstractBindingResult {
|
private class ValidationResult extends BeanPropertyBindingResult {
|
||||||
|
|
||||||
private final ConfigurationPropertyName name;
|
private final ConfigurationPropertyName name;
|
||||||
|
|
||||||
private Object target;
|
private final Object target;
|
||||||
|
|
||||||
protected ValidationResult(ConfigurationPropertyName name, Object target) {
|
protected ValidationResult(ConfigurationPropertyName name, Object target) {
|
||||||
super(null);
|
super(target, null);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
@ -160,11 +162,6 @@ public class ValidationBindHandler extends AbstractBindHandler {
|
||||||
return this.name.toString();
|
return this.name.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getTarget() {
|
|
||||||
return this.target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getFieldType(String field) {
|
public Class<?> getFieldType(String field) {
|
||||||
ResolvableType type = getBoundField(ValidationBindHandler.this.boundTypes, field);
|
ResolvableType type = getBoundField(ValidationBindHandler.this.boundTypes, field);
|
||||||
|
|
@ -177,7 +174,29 @@ public class ValidationBindHandler extends AbstractBindHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getActualFieldValue(String field) {
|
protected Object getActualFieldValue(String field) {
|
||||||
return getBoundField(ValidationBindHandler.this.boundResults, field);
|
Object boundField = getBoundField(ValidationBindHandler.this.boundResults, field);
|
||||||
|
if (boundField != null) {
|
||||||
|
return boundField;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return super.getActualFieldValue(field);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
if (isPropertyNotReadable(ex)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPropertyNotReadable(Throwable ex) {
|
||||||
|
while (ex != null) {
|
||||||
|
if (ex instanceof NotReadablePropertyException) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ex = ex.getCause();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getBoundField(Map<ConfigurationPropertyName, T> boundFields, String field) {
|
private <T> T getBoundField(Map<ConfigurationPropertyName, T> boundFields, String field) {
|
||||||
|
|
|
||||||
|
|
@ -713,6 +713,13 @@ class ConfigurationPropertiesTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadWhenConfigurationPropertiesWithValidDefaultValuesShouldNotFail() {
|
||||||
|
AnnotationConfigApplicationContext context = load(ValidatorPropertiesWithDefaultValues.class);
|
||||||
|
ValidatorPropertiesWithDefaultValues bean = context.getBean(ValidatorPropertiesWithDefaultValues.class);
|
||||||
|
assertThat(bean.getBar()).isEqualTo("a");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadWhenSetterThrowsValidationExceptionShouldFail() {
|
void loadWhenSetterThrowsValidationExceptionShouldFail() {
|
||||||
assertThatExceptionOfType(BeanCreationException.class)
|
assertThatExceptionOfType(BeanCreationException.class)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2021 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.context.properties;
|
||||||
|
|
||||||
|
import org.springframework.validation.Errors;
|
||||||
|
import org.springframework.validation.ValidationUtils;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for testing validation of properties that have default field values.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
@EnableConfigurationProperties
|
||||||
|
@ConfigurationProperties
|
||||||
|
class ValidatorPropertiesWithDefaultValues implements Validator {
|
||||||
|
|
||||||
|
private String bar = "a";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> type) {
|
||||||
|
return type == ValidatorPropertiesWithDefaultValues.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(Object target, Errors errors) {
|
||||||
|
ValidationUtils.rejectIfEmpty(errors, "bar", "foo.empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBar() {
|
||||||
|
return this.bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBar(String bar) {
|
||||||
|
this.bar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -49,4 +49,5 @@
|
||||||
<suppress files="LinuxDomainSocket" checks="FinalClass" message="SockaddrUn" />
|
<suppress files="LinuxDomainSocket" checks="FinalClass" message="SockaddrUn" />
|
||||||
<suppress files="BsdDomainSocket" checks="FinalClass" message="SockaddrUn" />
|
<suppress files="BsdDomainSocket" checks="FinalClass" message="SockaddrUn" />
|
||||||
<suppress files="StringSequence" checks="SpringMethodVisibility" message="isEmpty"/>
|
<suppress files="StringSequence" checks="SpringMethodVisibility" message="isEmpty"/>
|
||||||
|
<suppress files="ValidatorPropertiesWithDefaultValues\.java" checks="SpringMethodVisibility" />
|
||||||
</suppressions>
|
</suppressions>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue