美文网首页
SpringBoot:从request parameter中转换

SpringBoot:从request parameter中转换

作者: 花花大脸猫 | 来源:发表于2022-02-03 23:10 被阅读0次

对于@Controller/@RestController注解标记的类方法中,如何将request parameter接收到的参数转换为LocalDate等时间类型的变量,如下示例会做一个简单的说明:

@RestController
@RequestMapping("/api/")
final class DateTimeController {
 
    @RequestMapping(value = "date", method = RequestMethod.POST)
    public void processDate(@RequestParam("date") LocalDate date) {
        //Do something
    }
 
    @RequestMapping(value = "datetime", method = RequestMethod.POST)
    public void processDateTime(@RequestParam("datetime") LocalDateTime dateAndTime) {
        //Do something
    }
}

这样的写法我们都会觉得功能能够正常运行,实际情况并非如此,在真正运行过程中,访问api/data与api/datatime后台都会报错,报错信息如下所示:

2022-02-02 23:02:19.800  WARN 19352 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam java.time.LocalDate] for value '2021-12-13'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2021-12-13]]

这个错误提示比较明确,value '2021-12-13'对应的String字符串不能直接转换为java.time.LocalDate,那我们应该如何解决这个问题呢?

@DateTimeFormat注解闪亮登场

在java doc中此注解描述为:Declares that a field or method parameter should be formatted as a date or time,用于声明一个字段或者方法参数应该被格式化为日期或者时间。这么一看@DateTimeFormat能够应用于上述我们使用的场景,那么我们就先来试试。

demo1

@RestController
@RequestMapping("/api/")
final class DateTimeController {
 
    @RequestMapping(value = "date", method = RequestMethod.POST)
    public void processDate(@RequestParam("date") 
                            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
        //Do something
    }
}

使用默认的 ISO 8601 格式化 (yyyy-MM-dd),我们使用@DateTimeFormat注解并设置其属性为DateTimeFormat.ISO.DATE。

demo2

@RestController
@RequestMapping("/api/")
final class DateTimeController {
 
    @RequestMapping(value = "date", method = RequestMethod.POST)
    public void processDate(@RequestParam("date") 
                            @DateTimeFormat(pattern = "dd.MM.yyyy") LocalDate date) {
        //Do something
    }
}

使用自定义的日期格式(dd.MM.yyyy),我们使用@DateTimeFormat注解并设置自定义属性pattern的值为dd.MM.yyyy

demo3

@RestController
@RequestMapping("/api/")
final class DateTimeController {
 
    @RequestMapping(value = "datetime", method = RequestMethod.POST)
    public void processDateTime(@RequestParam("datetime") 
                                @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateAndTime) {
        //Do something
    }
}

如果我们想要用ISO 8601时间格式为:yyyy-MM-dd'T'HH:mm:ss.SSSZ,我们需要使用@DateTimeFormat注解,并设置iso属性值为DateTimeFormat.ISO.DATE_TIME

demo4

@RestController
@RequestMapping("/api/")
final class DateTimeController {
 
    @RequestMapping(value = "datetime", method = RequestMethod.POST)
    public void processDateTime(@RequestParam("datetime") 
                                @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss.SSSZ") LocalDateTime dateAndTime) {
        //Do something
    }
}

如果我们想用自定义的时间格式:dd.MM.yyyy HH:mm:ss.SSSZ,我们需要使用@DateTimeFormat注解,并设置pattern 属性值为dd.MM.yyyy HH:mm:ss.SSSZ

总结:

  • 我们可以应用@DateTimeFormat 注解在如下集中类型:java.util.Date, java.util.Calendar, java.lang.Long, Joda-Time 值类型,从spring 4和 jdk8 开始,到 JSR-310 java.time 类型都能支持
  • 如果我们想要使用ISO 8601格式化,我们需要指定@DateTimeFormat 注解的iso属性值
  • 如果我们想要使用自定义的格式化,我们需要指定@DateTimeFormat 注解的pattern 属性值

引用链接:https://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-parsing-date-and-time-information-from-a-request-parameter/

相关文章

网友评论

      本文标题:SpringBoot:从request parameter中转换

      本文链接:https://www.haomeiwen.com/subject/svnrkrtx.html