Skip to content

Commit b345fc8

Browse files
committed
Fix validation when key matching the prefix is set
Fixes gh-15597
1 parent ce62a96 commit b345fc8

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandler.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ public void onFinish(ConfigurationPropertyName name, Bindable<?> target,
7676
super.onFinish(name, target, context, result);
7777
}
7878

79+
@Override
80+
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target,
81+
BindContext context, Exception error) throws Exception {
82+
Object result = super.onFailure(name, target, context, error);
83+
validate(name, target, context, null);
84+
if (!this.exceptions.isEmpty()) {
85+
throw this.exceptions.pop();
86+
}
87+
return result;
88+
}
89+
7990
private void validate(ConfigurationPropertyName name, Bindable<?> target,
8091
BindContext context, Object result) {
8192
Object validationTarget = getValidationTarget(target, context, result);

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/validation/ValidationBindHandlerTests.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.junit.Before;
2828
import org.junit.Test;
2929

30+
import org.springframework.boot.context.properties.bind.AbstractBindHandler;
31+
import org.springframework.boot.context.properties.bind.BindContext;
3032
import org.springframework.boot.context.properties.bind.BindException;
3133
import org.springframework.boot.context.properties.bind.Bindable;
3234
import org.springframework.boot.context.properties.bind.Binder;
@@ -35,6 +37,7 @@
3537
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
3638
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
3739
import org.springframework.boot.origin.Origin;
40+
import org.springframework.core.convert.ConverterNotFoundException;
3841
import org.springframework.validation.FieldError;
3942
import org.springframework.validation.ObjectError;
4043
import org.springframework.validation.annotation.Validated;
@@ -57,12 +60,14 @@ public class ValidationBindHandlerTests {
5760

5861
private Binder binder;
5962

63+
private LocalValidatorFactoryBean validator;
64+
6065
@Before
6166
public void setup() {
6267
this.binder = new Binder(this.sources);
63-
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
64-
validator.afterPropertiesSet();
65-
this.handler = new ValidationBindHandler(validator);
68+
this.validator = new LocalValidatorFactoryBean();
69+
this.validator.afterPropertiesSet();
70+
this.handler = new ValidationBindHandler(this.validator);
6671
}
6772

6873
@Test
@@ -162,6 +167,34 @@ public void bindShouldNotValidateDepthGreaterThanZero() {
162167
this.handler);
163168
}
164169

170+
@Test
171+
public void bindShouldNotValidateIfOtherHandlersInChainThrowError() {
172+
this.sources.add(new MockConfigurationPropertySource("foo", "hello"));
173+
ExampleValidatedBean bean = new ExampleValidatedBean();
174+
assertThatExceptionOfType(BindException.class)
175+
.isThrownBy(
176+
() -> this.binder.bind("foo",
177+
Bindable.of(ExampleValidatedBean.class)
178+
.withExistingValue(bean),
179+
this.handler))
180+
.withCauseInstanceOf(ConverterNotFoundException.class);
181+
}
182+
183+
@Test
184+
public void bindShouldValidateIfOtherHandlersInChainIgnoreError() {
185+
TestHandler testHandler = new TestHandler();
186+
this.handler = new ValidationBindHandler(testHandler, this.validator);
187+
this.sources.add(new MockConfigurationPropertySource("foo", "hello"));
188+
ExampleValidatedBean bean = new ExampleValidatedBean();
189+
assertThatExceptionOfType(BindException.class)
190+
.isThrownBy(
191+
() -> this.binder.bind("foo",
192+
Bindable.of(ExampleValidatedBean.class)
193+
.withExistingValue(bean),
194+
this.handler))
195+
.withCauseInstanceOf(BindValidationException.class);
196+
}
197+
165198
private BindValidationException bindAndExpectValidationError(Runnable action) {
166199
try {
167200
action.run();
@@ -265,4 +298,14 @@ public int getAge() {
265298

266299
}
267300

301+
static class TestHandler extends AbstractBindHandler {
302+
303+
@Override
304+
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target,
305+
BindContext context, Exception error) throws Exception {
306+
return null;
307+
}
308+
309+
}
310+
268311
}

0 commit comments

Comments
 (0)