提交 4beb25b3 编写于 作者: B Brian Clozel

Reorder date formatting converter in registrar

Prior to this commit, the `DateFormatterRegistrar` would register the
annotation-based formatter before the pattern-based formatter. This
would create an issue when an application tries to convert a `String` to
an annotated `@DateTimeFormat Date`: since the converters are considered
in reversed order of registration in
`GenericConversionServicei#ConvertersForPair`, the pattern-based variant
would always be considered before the annotation-based variant,
overriding the developer's opinion.

This commit aligns the `DateFormatterRegistrar` with the
`DateTimeFormatterRegistrar` and registers the annotation-based variant
last.

Closes gh-23893
上级 43a86565
...@@ -61,14 +61,13 @@ public class DateFormatterRegistrar implements FormatterRegistrar { ...@@ -61,14 +61,13 @@ public class DateFormatterRegistrar implements FormatterRegistrar {
@Override @Override
public void registerFormatters(FormatterRegistry registry) { public void registerFormatters(FormatterRegistry registry) {
addDateConverters(registry); addDateConverters(registry);
registry.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory());
// In order to retain back compatibility we only register Date/Calendar // In order to retain back compatibility we only register Date/Calendar
// types when a user defined formatter is specified (see SPR-10105) // types when a user defined formatter is specified (see SPR-10105)
if (this.dateFormatter != null) { if (this.dateFormatter != null) {
registry.addFormatter(this.dateFormatter); registry.addFormatter(this.dateFormatter);
registry.addFormatterForFieldType(Calendar.class, this.dateFormatter); registry.addFormatterForFieldType(Calendar.class, this.dateFormatter);
} }
registry.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory());
} }
/** /**
......
...@@ -45,18 +45,19 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -45,18 +45,19 @@ import static org.assertj.core.api.Assertions.assertThat;
*/ */
public class DateFormattingTests { public class DateFormattingTests {
private final FormattingConversionService conversionService = new FormattingConversionService(); private FormattingConversionService conversionService;
private DataBinder binder; private DataBinder binder;
@BeforeEach @BeforeEach
public void setup() { void setup() {
DateFormatterRegistrar registrar = new DateFormatterRegistrar(); DateFormatterRegistrar registrar = new DateFormatterRegistrar();
setup(registrar); setup(registrar);
} }
private void setup(DateFormatterRegistrar registrar) { private void setup(DateFormatterRegistrar registrar) {
conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService); DefaultConversionService.addDefaultConverters(conversionService);
registrar.registerFormatters(conversionService); registrar.registerFormatters(conversionService);
...@@ -69,13 +70,13 @@ public class DateFormattingTests { ...@@ -69,13 +70,13 @@ public class DateFormattingTests {
} }
@AfterEach @AfterEach
public void tearDown() { void tearDown() {
LocaleContextHolder.setLocale(null); LocaleContextHolder.setLocale(null);
} }
@Test @Test
public void testBindLong() { void testBindLong() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("millis", "1256961600"); propertyValues.add("millis", "1256961600");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -84,7 +85,7 @@ public class DateFormattingTests { ...@@ -84,7 +85,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindLongAnnotated() { void testBindLongAnnotated() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("millisAnnotated", "10/31/09"); propertyValues.add("millisAnnotated", "10/31/09");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -93,7 +94,7 @@ public class DateFormattingTests { ...@@ -93,7 +94,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindCalendarAnnotated() { void testBindCalendarAnnotated() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("calendarAnnotated", "10/31/09"); propertyValues.add("calendarAnnotated", "10/31/09");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -102,7 +103,7 @@ public class DateFormattingTests { ...@@ -102,7 +103,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindDateAnnotated() { void testBindDateAnnotated() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotated", "10/31/09"); propertyValues.add("dateAnnotated", "10/31/09");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -111,7 +112,7 @@ public class DateFormattingTests { ...@@ -111,7 +112,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindDateArray() { void testBindDateArray() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotated", new String[]{"10/31/09 12:00 PM"}); propertyValues.add("dateAnnotated", new String[]{"10/31/09 12:00 PM"});
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -119,7 +120,7 @@ public class DateFormattingTests { ...@@ -119,7 +120,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindDateAnnotatedWithError() { void testBindDateAnnotatedWithError() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotated", "Oct X31, 2009"); propertyValues.add("dateAnnotated", "Oct X31, 2009");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -129,7 +130,7 @@ public class DateFormattingTests { ...@@ -129,7 +130,7 @@ public class DateFormattingTests {
@Test @Test
@Disabled @Disabled
public void testBindDateAnnotatedWithFallbackError() { void testBindDateAnnotatedWithFallbackError() {
// TODO This currently passes because of the Date(String) constructor fallback is used // TODO This currently passes because of the Date(String) constructor fallback is used
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotated", "Oct 031, 2009"); propertyValues.add("dateAnnotated", "Oct 031, 2009");
...@@ -139,7 +140,7 @@ public class DateFormattingTests { ...@@ -139,7 +140,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindDateAnnotatedPattern() { void testBindDateAnnotatedPattern() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotatedPattern", "10/31/09 1:05"); propertyValues.add("dateAnnotatedPattern", "10/31/09 1:05");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -148,7 +149,21 @@ public class DateFormattingTests { ...@@ -148,7 +149,21 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindDateTimeOverflow() { void testBindDateAnnotatedPatternWithGlobalFormat() {
DateFormatterRegistrar registrar = new DateFormatterRegistrar();
DateFormatter dateFormatter = new DateFormatter();
dateFormatter.setIso(ISO.DATE_TIME);
registrar.setFormatter(dateFormatter);
setup(registrar);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotatedPattern", "10/31/09 1:05");
binder.bind(propertyValues);
assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0);
assertThat(binder.getBindingResult().getFieldValue("dateAnnotatedPattern")).isEqualTo("10/31/09 1:05");
}
@Test
void testBindDateTimeOverflow() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("dateAnnotatedPattern", "02/29/09 12:00 PM"); propertyValues.add("dateAnnotatedPattern", "02/29/09 12:00 PM");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -156,7 +171,7 @@ public class DateFormattingTests { ...@@ -156,7 +171,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindISODate() { void testBindISODate() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("isoDate", "2009-10-31"); propertyValues.add("isoDate", "2009-10-31");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -165,7 +180,7 @@ public class DateFormattingTests { ...@@ -165,7 +180,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindISOTime() { void testBindISOTime() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("isoTime", "12:00:00.000-05:00"); propertyValues.add("isoTime", "12:00:00.000-05:00");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -174,7 +189,7 @@ public class DateFormattingTests { ...@@ -174,7 +189,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindISODateTime() { void testBindISODateTime() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("isoDateTime", "2009-10-31T12:00:00.000-08:00"); propertyValues.add("isoDateTime", "2009-10-31T12:00:00.000-08:00");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -183,7 +198,7 @@ public class DateFormattingTests { ...@@ -183,7 +198,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void testBindNestedDateAnnotated() { void testBindNestedDateAnnotated() {
MutablePropertyValues propertyValues = new MutablePropertyValues(); MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("children[0].dateAnnotated", "10/31/09"); propertyValues.add("children[0].dateAnnotated", "10/31/09");
binder.bind(propertyValues); binder.bind(propertyValues);
...@@ -192,7 +207,7 @@ public class DateFormattingTests { ...@@ -192,7 +207,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void dateToStringWithoutGlobalFormat() { void dateToStringWithoutGlobalFormat() {
Date date = new Date(); Date date = new Date();
Object actual = this.conversionService.convert(date, TypeDescriptor.valueOf(Date.class), TypeDescriptor.valueOf(String.class)); Object actual = this.conversionService.convert(date, TypeDescriptor.valueOf(Date.class), TypeDescriptor.valueOf(String.class));
String expected = date.toString(); String expected = date.toString();
...@@ -200,7 +215,7 @@ public class DateFormattingTests { ...@@ -200,7 +215,7 @@ public class DateFormattingTests {
} }
@Test @Test
public void dateToStringWithGlobalFormat() { void dateToStringWithGlobalFormat() {
DateFormatterRegistrar registrar = new DateFormatterRegistrar(); DateFormatterRegistrar registrar = new DateFormatterRegistrar();
registrar.setFormatter(new DateFormatter()); registrar.setFormatter(new DateFormatter());
setup(registrar); setup(registrar);
...@@ -212,14 +227,14 @@ public class DateFormattingTests { ...@@ -212,14 +227,14 @@ public class DateFormattingTests {
@Test // SPR-10105 @Test // SPR-10105
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void stringToDateWithoutGlobalFormat() { void stringToDateWithoutGlobalFormat() {
String string = "Sat, 12 Aug 1995 13:30:00 GM"; String string = "Sat, 12 Aug 1995 13:30:00 GM";
Date date = this.conversionService.convert(string, Date.class); Date date = this.conversionService.convert(string, Date.class);
assertThat(date).isEqualTo(new Date(string)); assertThat(date).isEqualTo(new Date(string));
} }
@Test // SPR-10105 @Test // SPR-10105
public void stringToDateWithGlobalFormat() { void stringToDateWithGlobalFormat() {
DateFormatterRegistrar registrar = new DateFormatterRegistrar(); DateFormatterRegistrar registrar = new DateFormatterRegistrar();
DateFormatter dateFormatter = new DateFormatter(); DateFormatter dateFormatter = new DateFormatter();
dateFormatter.setIso(ISO.DATE_TIME); dateFormatter.setIso(ISO.DATE_TIME);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册