Object/FieldError provides access to source object (exception/violation)

Issue: SPR-16372
This commit is contained in:
Juergen Hoeller
2018-02-09 18:42:56 +01:00
parent e873b18f43
commit 9bb7fcd997
6 changed files with 122 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -42,9 +42,11 @@ import org.junit.rules.ExpectedException;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.InvalidPropertyException;
import org.springframework.beans.MethodInvocationException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.NullValueInNestedPathException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
@@ -78,11 +80,11 @@ import static org.junit.Assert.*;
public class DataBinderTests {
@Rule
public ExpectedException expectedException = ExpectedException.none();
public final ExpectedException expectedException = ExpectedException.none();
@Test
public void testBindingNoErrors() throws Exception {
public void testBindingNoErrors() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
assertTrue(binder.isIgnoreUnknownFields());
@@ -116,7 +118,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithDefaultConversionNoErrors() throws Exception {
public void testBindingWithDefaultConversionNoErrors() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
assertTrue(binder.isIgnoreUnknownFields());
@@ -132,7 +134,7 @@ public class DataBinderTests {
}
@Test
public void testNestedBindingWithDefaultConversionNoErrors() throws Exception {
public void testNestedBindingWithDefaultConversionNoErrors() throws BindException {
TestBean rod = new TestBean(new TestBean());
DataBinder binder = new DataBinder(rod, "person");
assertTrue(binder.isIgnoreUnknownFields());
@@ -148,7 +150,7 @@ public class DataBinderTests {
}
@Test
public void testBindingNoErrorsNotIgnoreUnknown() throws Exception {
public void testBindingNoErrorsNotIgnoreUnknown() {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
binder.setIgnoreUnknownFields(false);
@@ -167,7 +169,7 @@ public class DataBinderTests {
}
@Test
public void testBindingNoErrorsWithInvalidField() throws Exception {
public void testBindingNoErrorsWithInvalidField() {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
MutablePropertyValues pvs = new MutablePropertyValues();
@@ -184,7 +186,7 @@ public class DataBinderTests {
}
@Test
public void testBindingNoErrorsWithIgnoreInvalid() throws Exception {
public void testBindingNoErrorsWithIgnoreInvalid() {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
binder.setIgnoreInvalidFields(true);
@@ -196,7 +198,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithErrors() throws Exception {
public void testBindingWithErrors() {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
MutablePropertyValues pvs = new MutablePropertyValues();
@@ -239,6 +241,7 @@ public class DataBinderTests {
assertEquals("typeMismatch", binder.getBindingResult().getFieldError("age").getCode());
assertEquals("32x", binder.getBindingResult().getFieldValue("age"));
assertEquals("32x", binder.getBindingResult().getFieldError("age").getRejectedValue());
assertTrue(binder.getBindingResult().getFieldError("age").getSource() instanceof TypeMismatchException);
assertEquals(0, tb.getAge());
assertTrue("Has touchy errors", br.hasFieldErrors("touchy"));
@@ -246,6 +249,7 @@ public class DataBinderTests {
assertEquals("methodInvocation", binder.getBindingResult().getFieldError("touchy").getCode());
assertEquals("m.y", binder.getBindingResult().getFieldValue("touchy"));
assertEquals("m.y", binder.getBindingResult().getFieldError("touchy").getRejectedValue());
assertTrue(binder.getBindingResult().getFieldError("touchy").getSource() instanceof MethodInvocationException);
assertNull(tb.getTouchy());
rod = new TestBean();
@@ -260,7 +264,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithSystemFieldError() throws Exception {
public void testBindingWithSystemFieldError() {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
MutablePropertyValues pvs = new MutablePropertyValues();
@@ -277,7 +281,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithErrorsAndCustomEditors() throws Exception {
public void testBindingWithErrorsAndCustomEditors() {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
binder.registerCustomEditor(String.class, "touchy", new PropertyEditorSupport() {
@@ -683,7 +687,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithAllowedFields() throws Exception {
public void testBindingWithAllowedFields() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod);
binder.setAllowedFields("name", "myparam");
@@ -698,7 +702,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithDisallowedFields() throws Exception {
public void testBindingWithDisallowedFields() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod);
binder.setDisallowedFields("age");
@@ -716,7 +720,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithAllowedAndDisallowedFields() throws Exception {
public void testBindingWithAllowedAndDisallowedFields() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod);
binder.setAllowedFields("name", "myparam");
@@ -735,7 +739,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithOverlappingAllowedAndDisallowedFields() throws Exception {
public void testBindingWithOverlappingAllowedAndDisallowedFields() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod);
binder.setAllowedFields("name", "age");
@@ -754,7 +758,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithAllowedFieldsUsingAsterisks() throws Exception {
public void testBindingWithAllowedFieldsUsingAsterisks() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod, "person");
binder.setAllowedFields("nam*", "*ouchy");
@@ -781,7 +785,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithAllowedAndDisallowedMapFields() throws Exception {
public void testBindingWithAllowedAndDisallowedMapFields() throws BindException {
TestBean rod = new TestBean();
DataBinder binder = new DataBinder(rod);
binder.setAllowedFields("someMap[key1]", "someMap[key2]");
@@ -809,7 +813,7 @@ public class DataBinderTests {
* Tests for required field, both null, non-existing and empty strings.
*/
@Test
public void testBindingWithRequiredFields() throws Exception {
public void testBindingWithRequiredFields() {
TestBean tb = new TestBean();
tb.setSpouse(new TestBean());
@@ -840,7 +844,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithRequiredMapFields() throws Exception {
public void testBindingWithRequiredMapFields() {
TestBean tb = new TestBean();
tb.setSpouse(new TestBean());
@@ -860,7 +864,7 @@ public class DataBinderTests {
}
@Test
public void testBindingWithNestedObjectCreation() throws Exception {
public void testBindingWithNestedObjectCreation() {
TestBean tb = new TestBean();
DataBinder binder = new DataBinder(tb, "person");
@@ -1828,7 +1832,7 @@ public class DataBinderTests {
}
@Test
public void testRejectWithoutDefaultMessage() throws Exception {
public void testRejectWithoutDefaultMessage() {
TestBean tb = new TestBean();
tb.setName("myName");
tb.setAge(99);
@@ -1875,7 +1879,7 @@ public class DataBinderTests {
}
@Test
public void testTrackDisallowedFields() throws Exception {
public void testTrackDisallowedFields() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.setAllowedFields("name", "age");
@@ -1895,7 +1899,7 @@ public class DataBinderTests {
}
@Test
public void testAutoGrowWithinDefaultLimit() throws Exception {
public void testAutoGrowWithinDefaultLimit() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
@@ -1907,7 +1911,7 @@ public class DataBinderTests {
}
@Test
public void testAutoGrowBeyondDefaultLimit() throws Exception {
public void testAutoGrowBeyondDefaultLimit() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
@@ -1924,7 +1928,7 @@ public class DataBinderTests {
}
@Test
public void testAutoGrowWithinCustomLimit() throws Exception {
public void testAutoGrowWithinCustomLimit() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.setAutoGrowCollectionLimit(10);
@@ -1937,7 +1941,7 @@ public class DataBinderTests {
}
@Test
public void testAutoGrowBeyondCustomLimit() throws Exception {
public void testAutoGrowBeyondCustomLimit() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.setAutoGrowCollectionLimit(10);
@@ -1971,7 +1975,7 @@ public class DataBinderTests {
}
@Test
public void testFieldErrorAccessVariations() throws Exception {
public void testFieldErrorAccessVariations() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
assertNull(binder.getBindingResult().getGlobalError());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@@ -32,6 +32,7 @@ import java.util.Set;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
import javax.validation.Valid;
import javax.validation.Validation;
@@ -48,6 +49,7 @@ import org.springframework.beans.BeanWrapperImpl;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.FieldError;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@@ -93,8 +95,11 @@ public class SpringValidatorAdapterTests {
assertThat(errors.getFieldErrorCount("password"), is(1));
assertThat(errors.getFieldValue("password"), is("pass"));
assertThat(messageSource.getMessage(errors.getFieldError("password"), Locale.ENGLISH),
is("Size of Password is must be between 8 and 128"));
FieldError error = errors.getFieldError("password");
assertNotNull(error);
assertThat(messageSource.getMessage(error, Locale.ENGLISH), is("Size of Password is must be between 8 and 128"));
assertTrue(error.getSource() instanceof ConstraintViolation);
assertThat(((ConstraintViolation) error.getSource()).getPropertyPath().toString(), is("password"));
}
@Test // SPR-13406
@@ -108,8 +113,11 @@ public class SpringValidatorAdapterTests {
assertThat(errors.getFieldErrorCount("password"), is(1));
assertThat(errors.getFieldValue("password"), is("password"));
assertThat(messageSource.getMessage(errors.getFieldError("password"), Locale.ENGLISH),
is("Password must be same value with Password(Confirm)"));
FieldError error = errors.getFieldError("password");
assertNotNull(error);
assertThat(messageSource.getMessage(error, Locale.ENGLISH), is("Password must be same value with Password(Confirm)"));
assertTrue(error.getSource() instanceof ConstraintViolation);
assertThat(((ConstraintViolation) error.getSource()).getPropertyPath().toString(), is("password"));
}
@Test // SPR-13406
@@ -124,10 +132,16 @@ public class SpringValidatorAdapterTests {
assertThat(errors.getFieldErrorCount("email"), is(1));
assertThat(errors.getFieldValue("email"), is("test@example.com"));
assertThat(errors.getFieldErrorCount("confirmEmail"), is(1));
assertThat(messageSource.getMessage(errors.getFieldError("email"), Locale.ENGLISH),
is("email must be same value with confirmEmail"));
assertThat(messageSource.getMessage(errors.getFieldError("confirmEmail"), Locale.ENGLISH),
is("Email required"));
FieldError error1 = errors.getFieldError("email");
FieldError error2 = errors.getFieldError("confirmEmail");
assertNotNull(error1);
assertNotNull(error2);
assertThat(messageSource.getMessage(error1, Locale.ENGLISH), is("email must be same value with confirmEmail"));
assertThat(messageSource.getMessage(error2, Locale.ENGLISH), is("Email required"));
assertTrue(error1.getSource() instanceof ConstraintViolation);
assertThat(((ConstraintViolation) error1.getSource()).getPropertyPath().toString(), is("email"));
assertTrue(error2.getSource() instanceof ConstraintViolation);
assertThat(((ConstraintViolation) error2.getSource()).getPropertyPath().toString(), is("confirmEmail"));
}
@Test // SPR-15123
@@ -144,10 +158,16 @@ public class SpringValidatorAdapterTests {
assertThat(errors.getFieldErrorCount("email"), is(1));
assertThat(errors.getFieldValue("email"), is("test@example.com"));
assertThat(errors.getFieldErrorCount("confirmEmail"), is(1));
assertThat(messageSource.getMessage(errors.getFieldError("email"), Locale.ENGLISH),
is("email must be same value with confirmEmail"));
assertThat(messageSource.getMessage(errors.getFieldError("confirmEmail"), Locale.ENGLISH),
is("Email required"));
FieldError error1 = errors.getFieldError("email");
FieldError error2 = errors.getFieldError("confirmEmail");
assertNotNull(error1);
assertNotNull(error2);
assertThat(messageSource.getMessage(error1, Locale.ENGLISH), is("email must be same value with confirmEmail"));
assertThat(messageSource.getMessage(error2, Locale.ENGLISH), is("Email required"));
assertTrue(error1.getSource() instanceof ConstraintViolation);
assertThat(((ConstraintViolation) error1.getSource()).getPropertyPath().toString(), is("email"));
assertTrue(error2.getSource() instanceof ConstraintViolation);
assertThat(((ConstraintViolation) error2.getSource()).getPropertyPath().toString(), is("confirmEmail"));
}
@Test // SPR-16177