Merge branch '2.2.x'

Closes gh-19622
pull/19623/head
Madhura Bhave 5 years ago
commit d510a7bd80

@ -16,10 +16,8 @@
package org.springframework.boot.context.properties.bind.validation; package org.springframework.boot.context.properties.bind.validation;
import java.util.Deque;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -52,7 +50,7 @@ public class ValidationBindHandler extends AbstractBindHandler {
private final Set<ConfigurationProperty> boundProperties = new LinkedHashSet<>(); private final Set<ConfigurationProperty> boundProperties = new LinkedHashSet<>();
private final Deque<BindValidationException> exceptions = new LinkedList<>(); private BindValidationException exception;
public ValidationBindHandler(Validator... validators) { public ValidationBindHandler(Validator... validators) {
this.validators = validators; this.validators = validators;
@ -94,7 +92,7 @@ public class ValidationBindHandler extends AbstractBindHandler {
this.boundTypes.clear(); this.boundTypes.clear();
this.boundResults.clear(); this.boundResults.clear();
this.boundProperties.clear(); this.boundProperties.clear();
this.exceptions.clear(); this.exception = null;
} }
@Override @Override
@ -105,13 +103,15 @@ public class ValidationBindHandler extends AbstractBindHandler {
} }
private void validate(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result) { private void validate(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result) {
if (this.exception == null) {
Object validationTarget = getValidationTarget(target, context, result); Object validationTarget = getValidationTarget(target, context, result);
Class<?> validationType = target.getBoxedType().resolve(); Class<?> validationType = target.getBoxedType().resolve();
if (validationTarget != null) { if (validationTarget != null) {
validateAndPush(name, validationTarget, validationType); validateAndPush(name, validationTarget, validationType);
} }
if (context.getDepth() == 0 && !this.exceptions.isEmpty()) { }
throw this.exceptions.pop(); if (context.getDepth() == 0 && this.exception != null) {
throw this.exception;
} }
} }
@ -134,7 +134,7 @@ public class ValidationBindHandler extends AbstractBindHandler {
} }
} }
if (result != null && result.hasErrors()) { if (result != null && result.hasErrors()) {
this.exceptions.push(new BindValidationException(result.getValidationErrors())); this.exception = new BindValidationException(result.getValidationErrors());
} }
} }

@ -201,6 +201,15 @@ class ValidationBindHandlerTests {
assertThat(cause.getMessage()).contains("rejected value [2]"); assertThat(cause.getMessage()).contains("rejected value [2]");
} }
@Test
void validationShouldBeSkippedIfPreviousValidationErrorPresent() {
this.sources.add(new MockConfigurationPropertySource("foo.inner.person-age", 2));
BindValidationException cause = bindAndExpectValidationError(() -> this.binder
.bind(ConfigurationPropertyName.of("foo"), Bindable.of(ExampleCamelCase.class), this.handler));
FieldError fieldError = (FieldError) cause.getValidationErrors().getAllErrors().get(0);
assertThat(fieldError.getField()).isEqualTo("personAge");
}
private BindValidationException bindAndExpectValidationError(Runnable action) { private BindValidationException bindAndExpectValidationError(Runnable action) {
try { try {
action.run(); action.run();

Loading…
Cancel
Save