Support lazy initialization of BindingResult when customize a MessageCodesResolver

Issue: SPR-15009
master
Kazuki Shimizu 8 years ago
parent 5169c51a6c
commit 9f229283fb
  1. 14
      spring-context/src/main/java/org/springframework/validation/DataBinder.java
  2. 72
      spring-context/src/test/java/org/springframework/validation/DataBinderTests.java

@ -150,6 +150,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
private ConversionService conversionService;
private MessageCodesResolver messageCodesResolver;
/**
* Create a new DataBinder instance, with default object name.
@ -253,6 +255,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
if (this.conversionService != null) {
result.initConversion(this.conversionService);
}
if (this.messageCodesResolver != null) {
result.setMessageCodesResolver(this.messageCodesResolver);
}
return result;
}
@ -279,6 +284,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
if (this.conversionService != null) {
result.initConversion(this.conversionService);
}
if (this.messageCodesResolver != null) {
result.setMessageCodesResolver(this.messageCodesResolver);
}
return result;
}
@ -486,7 +494,11 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
* @see DefaultMessageCodesResolver
*/
public void setMessageCodesResolver(MessageCodesResolver messageCodesResolver) {
getInternalBindingResult().setMessageCodesResolver(messageCodesResolver);
Assert.state(this.messageCodesResolver == null, "DataBinder is already initialized with MessageCodesResolver");
this.messageCodesResolver = messageCodesResolver;
if (this.bindingResult != null && messageCodesResolver != null) {
this.bindingResult.setMessageCodesResolver(messageCodesResolver);
}
}
/**

@ -40,6 +40,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.InvalidPropertyException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
@ -2013,6 +2014,77 @@ public class DataBinderTests {
binder.setAutoGrowCollectionLimit(257);
}
@Test // SPR-15009
public void testSetCustomMessageCodesResolverBeforeInitializeBindingResultForBeanPropertyAccess() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
DefaultMessageCodesResolver messageCodesResolver = new DefaultMessageCodesResolver();
messageCodesResolver.setPrefix("errors.");
binder.setMessageCodesResolver(messageCodesResolver);
binder.setAutoGrowCollectionLimit(512); // allow configuration after set a MessageCodesResolver
binder.initBeanPropertyAccess();
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("age", "invalid");
binder.bind(mpv);
assertEquals("errors.typeMismatch", binder.getBindingResult().getFieldError("age").getCode());
assertEquals(512, BeanWrapper.class.cast(binder.getInternalBindingResult().getPropertyAccessor()).getAutoGrowCollectionLimit());
}
@Test // SPR-15009
public void testSetCustomMessageCodesResolverBeforeInitializeBindingResultForDirectFieldAccess() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
DefaultMessageCodesResolver messageCodesResolver = new DefaultMessageCodesResolver();
messageCodesResolver.setPrefix("errors.");
binder.setMessageCodesResolver(messageCodesResolver);
binder.initDirectFieldAccess();
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("age", "invalid");
binder.bind(mpv);
assertEquals("errors.typeMismatch", binder.getBindingResult().getFieldError("age").getCode());
}
@Test // SPR-15009
public void testSetCustomMessageCodesResolverAfterInitializeBindingResult() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.initBeanPropertyAccess();
DefaultMessageCodesResolver messageCodesResolver = new DefaultMessageCodesResolver();
messageCodesResolver.setPrefix("errors.");
binder.setMessageCodesResolver(messageCodesResolver);
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("age", "invalid");
binder.bind(mpv);
assertEquals("errors.typeMismatch", binder.getBindingResult().getFieldError("age").getCode());
}
@Test // SPR-15009
public void testSetMessageCodesResolverIsNullAfterInitializeBindingResult() {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.initBeanPropertyAccess();
binder.setMessageCodesResolver(null);
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("age", "invalid");
binder.bind(mpv);
assertEquals("typeMismatch", binder.getBindingResult().getFieldError("age").getCode()); // Keep a default MessageCodesResolver
}
@Test // SPR-15009
public void testCallSetMessageCodesResolverTwice() {
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("DataBinder is already initialized with MessageCodesResolver");
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.setMessageCodesResolver(new DefaultMessageCodesResolver());
binder.setMessageCodesResolver(new DefaultMessageCodesResolver());
}
@SuppressWarnings("unused")
private static class BeanWithIntegerList {

Loading…
Cancel
Save