diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/DateTimeFormatters.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/DateTimeFormatters.java new file mode 100644 index 00000000000..89410942248 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/DateTimeFormatters.java @@ -0,0 +1,96 @@ +/* + * Copyright 2012-2020 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web.format; + +import java.time.format.DateTimeFormatter; +import java.time.format.ResolverStyle; + +import org.springframework.util.StringUtils; + +/** + * {@link DateTimeFormatter Formatters} for dates, times, and date-times. + * + * @author Andy Wilkinson + * @since 2.3.0 + */ +public class DateTimeFormatters { + + private DateTimeFormatter dateFormatter; + + private String datePattern; + + private DateTimeFormatter timeFormatter; + + private DateTimeFormatter dateTimeFormatter; + + /** + * Configures the date format using the given {@code pattern}. + * @param pattern the pattern for formatting dates + * @return {@code this} for chained method invocation + */ + public DateTimeFormatters dateFormat(String pattern) { + this.dateFormatter = formatter(pattern); + this.datePattern = pattern; + return this; + } + + /** + * Configures the time format using the given {@code pattern}. + * @param pattern the pattern for formatting times + * @return {@code this} for chained method invocation + */ + public DateTimeFormatters timeFormat(String pattern) { + this.timeFormatter = formatter(pattern); + return this; + } + + /** + * Configures the date-time format using the given {@code pattern}. + * @param pattern the pattern for formatting date-times + * @return {@code this} for chained method invocation + */ + public DateTimeFormatters dateTimeFormat(String pattern) { + this.dateTimeFormatter = formatter(pattern); + return this; + } + + DateTimeFormatter getDateFormatter() { + return this.dateFormatter; + } + + String getDatePattern() { + return this.datePattern; + } + + DateTimeFormatter getTimeFormatter() { + return this.timeFormatter; + } + + DateTimeFormatter getDateTimeFormatter() { + return this.dateTimeFormatter; + } + + boolean isCustomized() { + return this.dateFormatter != null || this.timeFormatter != null || this.dateTimeFormatter != null; + } + + private static DateTimeFormatter formatter(String pattern) { + return StringUtils.hasText(pattern) + ? DateTimeFormatter.ofPattern(pattern).withResolverStyle(ResolverStyle.SMART) : null; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java index cd82405b05c..2aa3c91dcf8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/format/WebConversionService.java @@ -17,7 +17,8 @@ package org.springframework.boot.autoconfigure.web.format; import java.time.format.DateTimeFormatter; -import java.time.format.ResolverStyle; +import java.util.function.Consumer; +import java.util.function.Supplier; import org.springframework.format.datetime.DateFormatter; import org.springframework.format.datetime.DateFormatterRegistrar; @@ -28,7 +29,6 @@ import org.springframework.format.number.money.Jsr354NumberFormatAnnotationForma import org.springframework.format.number.money.MonetaryAmountFormatter; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; /** * {@link org.springframework.format.support.FormattingConversionService} dedicated to web @@ -46,83 +46,70 @@ public class WebConversionService extends DefaultFormattingConversionService { private static final boolean JSR_354_PRESENT = ClassUtils.isPresent("javax.money.MonetaryAmount", WebConversionService.class.getClassLoader()); - private final String dateFormat; - - private final String timeFormat; - - private final String dateTimeFormat; - /** * Create a new WebConversionService that configures formatters with the provided date * format, or register the default ones if no custom format is provided. * @param dateFormat the custom date format to use for date conversions + * @deprecated since 2.3.0 in favor of + * {@link #WebConversionService(DateTimeFormatters)} */ + @Deprecated public WebConversionService(String dateFormat) { - this(dateFormat, null, null); + this(new DateTimeFormatters().dateFormat(dateFormat)); } /** - * Create a new WebConversionService that configures formatters with the provided date - * and time formats, or register the default ones if no custom formats are provided. - * @param dateFormat the custom date format to use for date conversions - * @param timeFormat the custom time format to use for time conversions - * @param dateTimeFormat the custom datetime format to use for datetime conversions + * Create a new WebConversionService that configures formatters with the provided + * date, time, and date-time formats, or registers the default if no custom format is + * provided. + * @param dateTimeFormatters the formatters to use for date, time, and date-time + * formatting + * @since 2.3.0 */ - public WebConversionService(String dateFormat, String timeFormat, String dateTimeFormat) { + public WebConversionService(DateTimeFormatters dateTimeFormatters) { super(false); - this.dateFormat = getNonEmptyFormat(dateFormat); - this.timeFormat = getNonEmptyFormat(timeFormat); - this.dateTimeFormat = getNonEmptyFormat(dateTimeFormat); - if (this.dateFormat != null || this.timeFormat != null || this.dateTimeFormat != null) { - addFormatters(); + if (dateTimeFormatters.isCustomized()) { + addFormatters(dateTimeFormatters); } else { addDefaultFormatters(this); } } - private void addFormatters() { + private void addFormatters(DateTimeFormatters dateTimeFormatters) { addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory()); if (JSR_354_PRESENT) { addFormatter(new CurrencyUnitFormatter()); addFormatter(new MonetaryAmountFormatter()); addFormatterForFieldAnnotation(new Jsr354NumberFormatAnnotationFormatterFactory()); } - registerJsr310(); - registerJavaDate(); + registerJsr310(dateTimeFormatters); + registerJavaDate(dateTimeFormatters); } - private void registerJsr310() { + private void registerJsr310(DateTimeFormatters dateTimeFormatters) { DateTimeFormatterRegistrar dateTime = new DateTimeFormatterRegistrar(); - if (this.dateFormat != null) { - dateTime.setDateFormatter( - DateTimeFormatter.ofPattern(this.dateFormat).withResolverStyle(ResolverStyle.SMART)); - } - - if (this.timeFormat != null) { - dateTime.setTimeFormatter( - DateTimeFormatter.ofPattern(this.timeFormat).withResolverStyle(ResolverStyle.SMART)); - } + configure(dateTimeFormatters::getDateFormatter, dateTime::setDateFormatter); + configure(dateTimeFormatters::getTimeFormatter, dateTime::setTimeFormatter); + configure(dateTimeFormatters::getDateTimeFormatter, dateTime::setDateTimeFormatter); + dateTime.registerFormatters(this); + } - if (this.dateTimeFormat != null) { - dateTime.setDateTimeFormatter( - DateTimeFormatter.ofPattern(this.dateTimeFormat).withResolverStyle(ResolverStyle.SMART)); + private void configure(Supplier supplier, Consumer consumer) { + DateTimeFormatter formatter = supplier.get(); + if (formatter != null) { + consumer.accept(formatter); } - - dateTime.registerFormatters(this); } - private void registerJavaDate() { + private void registerJavaDate(DateTimeFormatters dateTimeFormatters) { DateFormatterRegistrar dateFormatterRegistrar = new DateFormatterRegistrar(); - if (this.dateFormat != null) { - DateFormatter dateFormatter = new DateFormatter(this.dateFormat); + String datePattern = dateTimeFormatters.getDatePattern(); + if (datePattern != null) { + DateFormatter dateFormatter = new DateFormatter(datePattern); dateFormatterRegistrar.setFormatter(dateFormatter); } dateFormatterRegistrar.registerFormatters(this); } - private static String getNonEmptyFormat(final String format) { - return StringUtils.hasText(format) ? format : null; - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java index dab1d88e0da..1907d5460b1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java @@ -35,7 +35,9 @@ import org.springframework.boot.autoconfigure.validation.ValidationAutoConfigura import org.springframework.boot.autoconfigure.validation.ValidatorAdapter; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.format.DateTimeFormatters; import org.springframework.boot.autoconfigure.web.format.WebConversionService; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties.Format; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.boot.web.codec.CodecCustomizer; @@ -203,8 +205,9 @@ public class WebFluxAutoConfiguration { @Bean @Override public FormattingConversionService webFluxConversionService() { - WebConversionService conversionService = new WebConversionService(this.webFluxProperties.getDateFormat(), - this.webFluxProperties.getTimeFormat(), this.webFluxProperties.getDateTimeFormat()); + Format format = this.webFluxProperties.getFormat(); + WebConversionService conversionService = new WebConversionService(new DateTimeFormatters() + .dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime())); addFormatters(conversionService); return conversionService; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java index 88bd706e973..b4a991232b5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxProperties.java @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.web.reactive; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.util.StringUtils; /** @@ -33,20 +34,7 @@ public class WebFluxProperties { */ private String basePath; - /** - * Date format to use. For instance, `dd/MM/yyyy`. - */ - private String dateFormat; - - /** - * Time format to use. For instance, `HH:mm:ss`. - */ - private String timeFormat; - - /** - * Datetime format to use. For instance, `yyyy-MM-dd HH:mm:ss`. - */ - private String dateTimeFormat; + private final Format format = new Format(); /** * Path pattern used for static resources. @@ -74,28 +62,19 @@ public class WebFluxProperties { return candidate; } + @Deprecated + @DeprecatedConfigurationProperty(replacement = "spring.webflux.format.date") public String getDateFormat() { - return this.dateFormat; + return this.format.getDate(); } + @Deprecated public void setDateFormat(String dateFormat) { - this.dateFormat = dateFormat; + this.format.setDate(dateFormat); } - public String getTimeFormat() { - return this.timeFormat; - } - - public void setTimeFormat(final String timeFormat) { - this.timeFormat = timeFormat; - } - - public String getDateTimeFormat() { - return this.dateTimeFormat; - } - - public void setDateTimeFormat(final String dateTimeFormat) { - this.dateTimeFormat = dateTimeFormat; + public Format getFormat() { + return this.format; } public String getStaticPathPattern() { @@ -106,4 +85,47 @@ public class WebFluxProperties { this.staticPathPattern = staticPathPattern; } + public static class Format { + + /** + * Date format to use, for example `dd/MM/yyyy`. + */ + private String date; + + /** + * Time format to use, for example `HH:mm:ss`. + */ + private String time; + + /** + * Date-time format to use, for example `yyyy-MM-dd HH:mm:ss`. + */ + private String dateTime; + + public String getDate() { + return this.date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getTime() { + return this.time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getDateTime() { + return this.dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java index bb9e29a2687..062484c1fd2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java @@ -51,7 +51,9 @@ import org.springframework.boot.autoconfigure.validation.ValidatorAdapter; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.autoconfigure.web.ResourceProperties.Strategy; +import org.springframework.boot.autoconfigure.web.format.DateTimeFormatters; import org.springframework.boot.autoconfigure.web.format.WebConversionService; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.Format; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter; @@ -427,8 +429,9 @@ public class WebMvcAutoConfiguration { @Bean @Override public FormattingConversionService mvcConversionService() { - WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat(), - this.mvcProperties.getTimeFormat(), this.mvcProperties.getDateTimeFormat()); + Format format = this.mvcProperties.getFormat(); + WebConversionService conversionService = new WebConversionService(new DateTimeFormatters() + .dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime())); addFormatters(conversionService); return conversionService; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java index db7f55ebfe5..8f2aa4bd222 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java @@ -56,20 +56,7 @@ public class WebMvcProperties { */ private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER; - /** - * Date format to use. For instance, `dd/MM/yyyy`. - */ - private String dateFormat; - - /** - * Time format to use. For instance, `HH:mm:ss`. - */ - private String timeFormat; - - /** - * Datetime format to use. For instance, `yyyy-MM-dd HH:mm:ss`. - */ - private String dateTimeFormat; + private final Format format = new Format(); /** * Whether to dispatch TRACE requests to the FrameworkServlet doService method. @@ -149,28 +136,19 @@ public class WebMvcProperties { this.localeResolver = localeResolver; } + @Deprecated + @DeprecatedConfigurationProperty(replacement = "spring.mvc.format.date") public String getDateFormat() { - return this.dateFormat; + return this.format.getDate(); } + @Deprecated public void setDateFormat(String dateFormat) { - this.dateFormat = dateFormat; - } - - public String getTimeFormat() { - return this.timeFormat; + this.format.setDate(dateFormat); } - public void setTimeFormat(final String timeFormat) { - this.timeFormat = timeFormat; - } - - public String getDateTimeFormat() { - return this.dateTimeFormat; - } - - public void setDateTimeFormat(final String dateTimeFormat) { - this.dateTimeFormat = dateTimeFormat; + public Format getFormat() { + return this.format; } public boolean isIgnoreDefaultModelOnRedirect() { @@ -473,6 +451,49 @@ public class WebMvcProperties { } + public static class Format { + + /** + * Date format to use, for example `dd/MM/yyyy`. + */ + private String date; + + /** + * Time format to use, for example `HH:mm:ss`. + */ + private String time; + + /** + * Date-time format to use, for example `yyyy-MM-dd HH:mm:ss`. + */ + private String dateTime; + + public String getDate() { + return this.date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getTime() { + return this.time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getDateTime() { + return this.dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + } + public enum LocaleResolver { /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/format/WebConversionServiceTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/format/WebConversionServiceTests.java index e72f575b934..8f5b81e53b1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/format/WebConversionServiceTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/format/WebConversionServiceTests.java @@ -16,8 +16,13 @@ package org.springframework.boot.autoconfigure.web.format; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; import java.util.Date; import org.junit.jupiter.api.Test; @@ -32,6 +37,14 @@ import static org.assertj.core.api.Assertions.assertThat; */ class WebConversionServiceTests { + @Test + void defaultDateFormat() { + WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()); + LocalDate date = LocalDate.of(2020, 4, 26); + assertThat(conversionService.convert(date, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(date)); + } + @Test void customDateFormatWithJavaUtilDate() { customDateFormat(Date.from(ZonedDateTime.of(2018, 1, 1, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant())); @@ -43,35 +56,49 @@ class WebConversionServiceTests { } @Test - void customTimeFormatWithJavaTime() { - customTimeFormat(java.time.LocalTime.of(13, 37, 42)); + void defaultTimeFormat() { + WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()); + LocalTime time = LocalTime.of(12, 45, 23); + assertThat(conversionService.convert(time, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(time)); } @Test - void customDateTimeFormatWithJavaTime() { - customDateTimeFormat(java.time.LocalDateTime.of(2019, 10, 28, 13, 37, 42)); - } - - private void customDateFormat(Object input) { - WebConversionService conversionService = new WebConversionService("dd*MM*yyyy"); - assertThat(conversionService.convert(input, String.class)).isEqualTo("01*01*2018"); + void customTimeFormat() { + WebConversionService conversionService = new WebConversionService( + new DateTimeFormatters().timeFormat("HH*mm*ss")); + LocalTime time = LocalTime.of(12, 45, 23); + assertThat(conversionService.convert(time, String.class)).isEqualTo("12*45*23"); } - private void customTimeFormat(Object input) { - WebConversionService conversionService = new WebConversionService(null, "HH*mm*ss", null); - assertThat(conversionService.convert(input, String.class)).isEqualTo("13*37*42"); + @Test + void defaultDateTimeFormat() { + WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()); + LocalDateTime dateTime = LocalDateTime.of(2020, 4, 26, 12, 45, 23); + assertThat(conversionService.convert(dateTime, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(dateTime)); } - private void customDateTimeFormat(Object input) { - WebConversionService conversionService = new WebConversionService(null, null, "dd*MM*yyyy HH*mm*ss"); - assertThat(conversionService.convert(input, String.class)).isEqualTo("28*10*2019 13*37*42"); + @Test + void customDateTimeFormat() { + WebConversionService conversionService = new WebConversionService( + new DateTimeFormatters().dateTimeFormat("dd*MM*yyyy HH*mm*ss")); + LocalDateTime dateTime = LocalDateTime.of(2020, 4, 26, 12, 45, 23); + assertThat(conversionService.convert(dateTime, String.class)).isEqualTo("26*04*2020 12*45*23"); } @Test void convertFromStringToDate() { - WebConversionService conversionService = new WebConversionService("yyyy-MM-dd"); + WebConversionService conversionService = new WebConversionService( + new DateTimeFormatters().dateFormat("yyyy-MM-dd")); java.time.LocalDate date = conversionService.convert("2018-01-01", java.time.LocalDate.class); assertThat(date).isEqualTo(java.time.LocalDate.of(2018, 1, 1)); } + private void customDateFormat(Object input) { + WebConversionService conversionService = new WebConversionService( + new DateTimeFormatters().dateFormat("dd*MM*yyyy")); + assertThat(conversionService.convert(input, String.class)).isEqualTo("01*01*2018"); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java index 463fb25de0c..af0efa7ea5f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java @@ -16,8 +16,12 @@ package org.springframework.boot.autoconfigure.web.reactive; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; import java.util.Collections; import java.util.Date; import java.util.List; @@ -185,7 +189,7 @@ class WebFluxAutoConfigurationTests { } @Test - void noDateFormat() { + void defaultDateFormat() { this.contextRunner.run((context) -> { FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); Date date = Date.from(ZonedDateTime.of(1988, 6, 25, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant()); @@ -195,7 +199,7 @@ class WebFluxAutoConfigurationTests { } @Test - void overrideDateFormat() { + void customDateFormatWithDeprecatedProperty() { this.contextRunner.withPropertyValues("spring.webflux.date-format:dd*MM*yyyy").run((context) -> { FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); Date date = Date.from(ZonedDateTime.of(1988, 6, 25, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant()); @@ -203,6 +207,53 @@ class WebFluxAutoConfigurationTests { }); } + @Test + void customDateFormat() { + this.contextRunner.withPropertyValues("spring.webflux.format.date:dd*MM*yyyy").run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + Date date = Date.from(ZonedDateTime.of(1988, 6, 25, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant()); + assertThat(conversionService.convert(date, String.class)).isEqualTo("25*06*1988"); + }); + } + + @Test + void defaultTimeFormat() { + this.contextRunner.run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalTime time = LocalTime.of(11, 43, 10); + assertThat(conversionService.convert(time, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(time)); + }); + } + + @Test + void customTimeFormat() { + this.contextRunner.withPropertyValues("spring.webflux.format.time=HH:mm:ss").run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalTime time = LocalTime.of(11, 43, 10); + assertThat(conversionService.convert(time, String.class)).isEqualTo("11:43:10"); + }); + } + + @Test + void defaultDateTimeFormat() { + this.contextRunner.run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalDateTime dateTime = LocalDateTime.of(2020, 4, 28, 11, 43, 10); + assertThat(conversionService.convert(dateTime, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(dateTime)); + }); + } + + @Test + void customDateTimeTimeFormat() { + this.contextRunner.withPropertyValues("spring.webflux.format.date-time=yyyy-MM-dd HH:mm:ss").run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalDateTime dateTime = LocalDateTime.of(2020, 4, 28, 11, 43, 10); + assertThat(conversionService.convert(dateTime, String.class)).isEqualTo("2020-04-28 11:43:10"); + }); + } + @Test void validatorWhenNoValidatorShouldUseDefault() { this.contextRunner.run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java index 4d4f5140b2e..2877ae02515 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java @@ -16,8 +16,12 @@ package org.springframework.boot.autoconfigure.web.servlet; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; import java.util.Collections; import java.util.Date; import java.util.LinkedHashMap; @@ -322,7 +326,7 @@ class WebMvcAutoConfigurationTests { } @Test - void noDateFormat() { + void defaultDateFormat() { this.contextRunner.run((context) -> { FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); Date date = Date.from(ZonedDateTime.of(1988, 6, 25, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant()); @@ -332,7 +336,16 @@ class WebMvcAutoConfigurationTests { } @Test - void overrideDateFormat() { + void customDateFormat() { + this.contextRunner.withPropertyValues("spring.mvc.format.date:dd*MM*yyyy").run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + Date date = Date.from(ZonedDateTime.of(1988, 6, 25, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant()); + assertThat(conversionService.convert(date, String.class)).isEqualTo("25*06*1988"); + }); + } + + @Test + void customDateFormatWithDeprecatedProperty() { this.contextRunner.withPropertyValues("spring.mvc.date-format:dd*MM*yyyy").run((context) -> { FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); Date date = Date.from(ZonedDateTime.of(1988, 6, 25, 20, 30, 0, 0, ZoneId.systemDefault()).toInstant()); @@ -340,6 +353,44 @@ class WebMvcAutoConfigurationTests { }); } + @Test + void defaultTimeFormat() { + this.contextRunner.run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalTime time = LocalTime.of(11, 43, 10); + assertThat(conversionService.convert(time, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(time)); + }); + } + + @Test + void customTimeFormat() { + this.contextRunner.withPropertyValues("spring.mvc.format.time=HH:mm:ss").run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalTime time = LocalTime.of(11, 43, 10); + assertThat(conversionService.convert(time, String.class)).isEqualTo("11:43:10"); + }); + } + + @Test + void defaultDateTimeFormat() { + this.contextRunner.run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalDateTime dateTime = LocalDateTime.of(2020, 4, 28, 11, 43, 10); + assertThat(conversionService.convert(dateTime, String.class)) + .isEqualTo(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(dateTime)); + }); + } + + @Test + void customDateTimeTimeFormat() { + this.contextRunner.withPropertyValues("spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss").run((context) -> { + FormattingConversionService conversionService = context.getBean(FormattingConversionService.class); + LocalDateTime dateTime = LocalDateTime.of(2020, 4, 28, 11, 43, 10); + assertThat(conversionService.convert(dateTime, String.class)).isEqualTo("2020-04-28 11:43:10"); + }); + } + @Test void noMessageCodesResolver() { this.contextRunner.run(