Working with Date Parameters in Spring – 在Spring中使用日期参数

最后修改: 2018年 10月 24日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this short tutorial, we’ll learn how to accept Date, LocalDate, and LocalDateTime parameters in Spring REST requests, both at the request and application level.

在这个简短的教程中,我们将学习如何在Spring REST请求中接受DateLocalDate,LocalDateTime参数,包括在请求和应用程序级别。

2. The Problem

2.问题

Let’s consider a controller with three methods that accepts Date, LocalDate and LocalDateTime parameters:

让我们考虑一个有三个方法的控制器,接受DateLocalDateLocalDateTime参数。

@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) {
        // ...
    }
}

When sending a POST request to any of those methods with a parameter formatted in accordance with ISO 8601, we’ll get an exception.

当向这些方法中的任何一个发送POST请求时,如果参数的格式符合ISO 8601的规定,我们将得到一个异常。

For example, when sending “2018-10-22” to the /date endpoint, we’ll get a bad request error with a message similar to this:

例如,当向/date端点发送 “2018-10-22 “时,我们会得到一个错误的请求,信息类似于此。

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

This is because by default, Spring cannot convert String parameters to any date or time object.

这是因为在默认情况下,Spring不能将String参数转换为任何日期或时间对象。

3. Convert Date Parameters on Request Level

3.在请求层面上转换日期参数

One of the ways to handle this problem is to annotate the parameters with the @DateTimeFormat annotation, and provide a formatting pattern parameter:

处理这个问题的方法之一是用@DateTimeFormat注解参数,并提供一个格式化模式参数。

@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) {
        // ...
    }
}

This way the Strings will be properly converted to date objects, provided the Strings are formatted using the ISO 8601 format.

这样,字符串将被正确地转换为日期对象,前提是字符串的格式为ISO 8601格式。

We can also use our own conversion patterns by providing a pattern parameter in the @DateTimeFormat annotation:

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

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

4. Convert Date Parameters at the Application Level

4.在应用层面转换日期参数

Another way to handle date and time object conversion in Spring is to provide a global configuration. By following the official documentation, we should extend the WebMvcConfigurationSupport configuration and its mvcConversionService method:

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

@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;
    }
}

First, we create DefaultFormattingConversionService with a false parameter, which means Spring won’t register any formatters by default.

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

Then we need to register our custom formats for date and date-time parameters. We do this by registering two custom formatting registrars. The first one, DateTimeFormatterRegistar, will be responsible for parsing the LocalDate and LocaDateTime objects. The second one, DateFormattingRegistrar, will handle the Date object.

然后,我们需要为日期和日期时间参数注册我们的自定义格式。我们通过注册两个自定义格式化注册器来实现这一目标。第一个,DateTimeFormatterRegistar,将负责解析LocalDateLocaDateTime对象。第二个,DateFormattingRegistrar,/em>将处理Date对象。

5. Configure Date-Time in Properties File

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

Spring also gives us the option to set global date-time formats via the application properties file. There are three individual parameters for the date, date-time, and time format:

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

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

All of these parameters can be replaced with an iso value. For example, setting the date-time parameter as:

所有这些参数都可以用一个iso值来代替。例如,将日期-时间参数设置为。

spring.mvc.format.date-time=iso

will be equal to ISO-8601 formatting:

将等于ISO-8601的格式化。

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

6. Conclusion

6.结语

In this article, we learned how to accept the date parameters in Spring MVC requests. We discussed how to do this per request, and globally.

在这篇文章中,我们学习了如何在Spring MVC请求中接受日期参数。我们讨论了如何在每个请求中以及在全局中这样做。

We also learned how to create our own date formatting patterns.

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

As always, all source code is available over on GitHub.

一如既往,所有的源代码都可以在GitHub上找到