在Spring中使用日期参数

转自:https://www.baeldung.com/spring-date-parameters

1.简介

在这个简短的教程中,我们将看看如何在请求和应用程序级别上在Spring REST请求中接受Date,LocalDate和LocalDateTime参数。

2.问题

让我们考虑一种具有三种接受Date,LocalDate和LocalDateTime参数的方法的控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RestController
public class DateTimeController {

@PostMapping("/date")
public void date(@RequestParam("date") Date date) {
// ...
}

@PostMapping("/localdate")
public void localDate(@RequestParam("localDate") LocalDate localDate) {
// ...
}

@PostMapping("/localdatetime")
public void dateTime(@RequestParam("localDateTime") LocalDateTime localDateTime) {
// ...
}
}

将POST请求发送到具有根据ISO 8601格式设置的参数的任何方法时,我们将获得异常。

例如,当将 “2018-10-22” 发送到 /date 接口时,我们将收到bad request错误,并显示类似以下消息:

1
2
Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate'; 
nested exception is org.springframework.core.convert.ConversionFailedException.

这是因为默认情况下,Spring无法将字符串参数转换为任何日期或时间对象。

3.在请求级别转换日期参数

解决此问题的方法之一是使用@DateTimeFormat注解对参数进行批注并提供格式化模式参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RestController
public class DateTimeController {

@PostMapping("/date")
public void date(@RequestParam("date")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date date) {
// ...
}

@PostMapping("/local-date")
public void localDate(@RequestParam("localDate")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate) {
// ...
}

@PostMapping("/local-date-time")
public void dateTime(@RequestParam("localDateTime")
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateTime) {
// ...
}
}

这样,只要将字符串使用ISO 8601格式进行格式化,就可以将字符串正确转换为日期对象。

我们还可以使用自己的转换格式。 我们可以在@DateTimeFormat注解中提供一个格式参数:

1
2
3
4
5
@PostMapping("/date")
public void date(@RequestParam("date")
@DateTimeFormat(pattern = "dd.MM.yyyy") Date date) {
// ...
}

4.在应用程序级别转换日期参数

在Spring中处理日期和时间对象转换的另一种方法是提供全局配置。 通过遵循官方文档,我们应该扩展WebMvcConfigurationSupport配置并扩展其mvcConversionService方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
public class DateTimeConfig extends WebMvcConfigurationSupport {

@Bean
@Override
public FormattingConversionService mvcConversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);

DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));
dateTimeRegistrar.registerFormatters(conversionService);

DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
dateRegistrar.setFormatter(new DateFormatter("dd.MM.yyyy"));
dateRegistrar.registerFormatters(conversionService);

return conversionService;
}
}

首先,我们使用false参数创建DefaultFormattingConversionService,这意味着Spring默认不会注册任何格式化器。

接下来,我们需要为日期和日期时间参数注册自定义格式。 为此,我们需要注册两个自定义格式注册器。 第一个– DateTimeFormatterRegistar将负责解析LocalDateLocaDateTime对象。 第二个– DateFormattingRegistrar将处理Date对象。

5.在属性文件中配置日期时间

Spring为我们提供了一个通过应用程序属性文件设置全局日期时间格式的选项。 日期,日期时间和时间格式有三个单独的参数:

1
2
3
spring.mvc.format.date=yyyy-MM-dd
spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss
spring.mvc.format.time=HH:mm:ss

所有这些参数都可以用iso值代替。 例如,将date-time参数设置为:

1
spring.mvc.format.date-time=iso

将等于ISO-8601格式:

1
spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss

6.总结

在本文中,我们学习了如何在Spring MVC请求中接受日期参数。 我们已经介绍了如何根据请求以及全局进行操作。

我们还学习了如何创建自己的日期格式模式。

源码在GitHub上:地址