Merge branch '2.1.x'
Closes gh-17422
This commit is contained in:
@@ -92,7 +92,9 @@ public interface BindHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when binding finishes, regardless of whether the property was bound or not.
|
||||
* Called when binding finishes with either bound or unbound result. This method will
|
||||
* not be called when binding failed, even if a handler rurns a result from
|
||||
* {@link #onFailure}.
|
||||
* @param name the name of the element being bound
|
||||
* @param target the item being bound
|
||||
* @param context the bind context
|
||||
|
||||
@@ -65,6 +65,17 @@ public class ValidationBindHandler extends AbstractBindHandler {
|
||||
return super.onSuccess(name, target, context, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Exception error)
|
||||
throws Exception {
|
||||
Object result = super.onFailure(name, target, context, error);
|
||||
if (result != null) {
|
||||
this.exceptions.clear();
|
||||
}
|
||||
validate(name, target, context, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result)
|
||||
throws Exception {
|
||||
@@ -72,14 +83,6 @@ public class ValidationBindHandler extends AbstractBindHandler {
|
||||
super.onFinish(name, target, context, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Exception error)
|
||||
throws Exception {
|
||||
Object result = super.onFailure(name, target, context, error);
|
||||
validate(name, target, context, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void validate(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result) {
|
||||
Object validationTarget = getValidationTarget(target, context, result);
|
||||
Class<?> validationType = target.getBoxedType().resolve();
|
||||
|
||||
@@ -167,7 +167,7 @@ class ValidationBindHandlerTests {
|
||||
|
||||
@Test
|
||||
void bindShouldValidateIfOtherHandlersInChainIgnoreError() {
|
||||
TestHandler testHandler = new TestHandler();
|
||||
TestHandler testHandler = new TestHandler(null);
|
||||
this.handler = new ValidationBindHandler(testHandler, this.validator);
|
||||
this.sources.add(new MockConfigurationPropertySource("foo", "hello"));
|
||||
ExampleValidatedBean bean = new ExampleValidatedBean();
|
||||
@@ -177,6 +177,21 @@ class ValidationBindHandlerTests {
|
||||
.withCauseInstanceOf(BindValidationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindShouldValidateIfOtherHandlersInChainReplaceErrorWithResult() {
|
||||
TestHandler testHandler = new TestHandler(new ExampleValidatedBeanSubclass());
|
||||
this.handler = new ValidationBindHandler(testHandler, this.validator);
|
||||
this.sources.add(new MockConfigurationPropertySource("foo", "hello"));
|
||||
this.sources.add(new MockConfigurationPropertySource("foo.age", "bad"));
|
||||
this.sources.add(new MockConfigurationPropertySource("foo.years", "99"));
|
||||
ExampleValidatedBean bean = new ExampleValidatedBean();
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
.isThrownBy(() -> this.binder.bind("foo",
|
||||
Bindable.of(ExampleValidatedBean.class).withExistingValue(bean), this.handler))
|
||||
.withCauseInstanceOf(BindValidationException.class)
|
||||
.satisfies((ex) -> assertThat(ex.getCause()).hasMessageContaining("years"));
|
||||
}
|
||||
|
||||
private BindValidationException bindAndExpectValidationError(Runnable action) {
|
||||
try {
|
||||
action.run();
|
||||
@@ -219,6 +234,25 @@ class ValidationBindHandlerTests {
|
||||
|
||||
}
|
||||
|
||||
public static class ExampleValidatedBeanSubclass extends ExampleValidatedBean {
|
||||
|
||||
@Min(100)
|
||||
private int years;
|
||||
|
||||
ExampleValidatedBeanSubclass() {
|
||||
setAge(20);
|
||||
}
|
||||
|
||||
public int getYears() {
|
||||
return this.years;
|
||||
}
|
||||
|
||||
public void setYears(int years) {
|
||||
this.years = years;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Validated
|
||||
public static class ExampleValidatedWithNestedBean {
|
||||
|
||||
@@ -286,10 +320,16 @@ class ValidationBindHandlerTests {
|
||||
|
||||
static class TestHandler extends AbstractBindHandler {
|
||||
|
||||
private Object result;
|
||||
|
||||
TestHandler(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context,
|
||||
Exception error) throws Exception {
|
||||
return null;
|
||||
return this.result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user