如何在Spring MVC中用@RequestParam解析不同ISO日期时间格式
处理多种类ISO格式的日期时间解析方案
嘿,这个问题我之前在对接第三方API的时候也遇到过!Spring默认的日期解析规则确实没法覆盖这些五花八门的ISO变种格式,不过咱们可以通过自定义格式化逻辑轻松搞定,给你两种实用的方案:
方案一:控制器级别的局部绑定(针对单个控制器)
如果只需要在某个特定控制器里处理这些格式,可以用@InitBinder来注册自定义的日期编辑器:
@RestController class SomeApiController { @InitBinder fun initBinder(binder: WebDataBinder) { // 构建支持所有目标格式的DateTimeFormatter val customFormatter = DateTimeFormatterBuilder() // 基础的日期时间部分:yyyy-MM-dd'T'HH:mm:ss .appendPattern("yyyy-MM-dd'T'HH:mm:ss") // 可选的毫秒部分(0-3位,比如.410、.41或者无) .optionalStart() .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) .optionalEnd() // 可选的时区偏移部分,支持三种格式:XXX(+00:00)、XX(+0000)、X(+00/Z) .optionalStart() .appendPattern("[XXX][XX][X]") .optionalEnd() .toFormatter() // 注册自定义编辑器,绑定到OffsetDateTime类型 binder.registerCustomEditor(OffsetDateTime::class.java, object : PropertyEditorSupport() { override fun setAsText(text: String?) { value = text?.takeIf { it.isNotBlank() }?.let { OffsetDateTime.parse(it, customFormatter) } } }) } @RequestMapping(value = ["/some/api/call"], method = [RequestMethod.GET]) fun someApiCall(@RequestParam("from") from: OffsetDateTime): ResponseEntity<String> { // 业务逻辑处理 return ResponseEntity.ok("Parsed date: $from") } }
方案二:全局配置(全应用生效)
如果多个控制器都需要处理这些格式,推荐全局配置,一劳永逸:
@Configuration class GlobalDateTimeConfig : WebMvcConfigurer { override fun addFormatters(registry: FormatterRegistry) { val customFormatter = DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd'T'HH:mm:ss") .optionalStart() .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) .optionalEnd() .optionalStart() .appendPattern("[XXX][XX][X]") .optionalEnd() .toFormatter() // 注册全局的OffsetDateTime格式化器 registry.addFormatter(object : Formatter<OffsetDateTime> { override fun parse(text: String, locale: Locale): OffsetDateTime { return OffsetDateTime.parse(text, customFormatter) } override fun print(obj: OffsetDateTime, locale: Locale): String { return obj.format(customFormatter) } }) } }
关键注意点
- 建议使用
OffsetDateTime作为参数类型,因为所有目标格式都带时区偏移,用这个类型能准确保留时区信息,避免时区转换错误。 - 自定义的
DateTimeFormatter通过optionalStart()和optionalEnd()实现了对可选部分(毫秒、时区偏移)的支持,同时用[XXX][XX][X]的模式匹配三种不同的时区偏移格式。
内容的提问来源于stack exchange,提问作者Bastian Voigt
相关产品推荐
相关产品推荐

