首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用Spring @RequestParam解析不同的ISO日期/时间格式

如何用Spring @RequestParam解析不同的ISO日期/时间格式
EN

Stack Overflow用户
提问于 2018-05-07 14:12:41
回答 2查看 2.2K关注 0票数 2

我们的Rest由几个外部方使用。它们都使用"ISO-ish“格式,但时区偏移量的格式略有不同。这些是我们看到的一些最常见的格式:

  1. 2018-01-01T15:56:31.410Z
  2. 2018-01-01T15:56:31.41Z
  3. 2018-01-01T15:56:31Z
  4. 2018-01-01T15:56:31+00:00
  5. 2018-01-01T15:56:31+0000
  6. 2018-01-01T15:56:31+00

在我的控制器中,我使用以下注释:

代码语言:javascript
复制
@RequestMapping(value = ["/some/api/call"], method = [GET])
fun someApiCall(
  @RequestParam("from") 
  @DateTimeFormat(iso = ISO.DATE_TIME) 
  from: OffsetDateTime
) {
  ...
}

它对变体1-4进行了很好的分析,但对于变体5和6产生了一个400坏的请求错误,但有以下例外:

代码语言:javascript
复制
Caused by: java.time.format.DateTimeParseException: Text '2018-01-01T13:37:00.001+00' could not be parsed, unparsed text found at index 23
  at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1952)
  at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

如何使它接受所有上述ISO格式变体(即使它们不是100%符合ISO标准)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-07 15:10:55

我通过添加一个自定义格式化注释来解决这个问题:

代码语言:javascript
复制
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
annotation class IsoDateTime

加上一个FormatterFactory:

代码语言:javascript
复制
class DefensiveDateTimeFormatterFactory : 
EmbeddedValueResolutionSupport(), AnnotationFormatterFactory<IsoDateTime> 
{
  override fun getParser(annotation: IsoDateTime?, fieldType: Class<*>?): Parser<*> {
    return Parser<OffsetDateTime> { text, _ -> OffsetDateTime.parse(text, JacksonConfig.defensiveFormatter) }
  }

  override fun getPrinter(annotation: IsoDateTime, fieldType: Class<*>): Printer<*> {
    return Printer<OffsetDateTime> { obj, _ -> obj.format(DateTimeFormatter.ISO_DATE_TIME) }
  }

  override fun getFieldTypes(): MutableSet<Class<*>> {
    return mutableSetOf(OffsetDateTime::class.java)
  }
}

实际的DateTimeFormat类来自于我的另一个问题,如何使用Jackson和java.time解析不同的ISO日期/时间格式?

并使用WebMvcConfigurer将其添加到Spring:

代码语言:javascript
复制
@Configuration
open class WebMvcConfiguration : WebMvcConfigurer {
  override fun addFormatters(registry: FormatterRegistry) {
    registry.addFormatterForFieldAnnotation(DefensiveDateTimeFormatterFactory())
  }
}
票数 2
EN

Stack Overflow用户

发布于 2018-05-07 14:29:13

您可以获得400-Bad Request,因为格式5和6不是ISO规范的一部分。

如果您查看时区设计器,它可以是Z+hh:mm-hh:mm之一。

ISO-8601格式的正式列表可以找到这里

代码语言:javascript
复制
   Year:
      YYYY (eg 1997)
   Year and month:
      YYYY-MM (eg 1997-07)
   Complete date:
      YYYY-MM-DD (eg 1997-07-16)
   Complete date plus hours and minutes:
      YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
   Complete date plus hours, minutes and seconds:
      YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
   Complete date plus hours, minutes, seconds and a decimal fraction of a second
      YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)

其中:

代码语言:javascript
复制
     YYYY = four-digit year
     MM   = two-digit month (01=January, etc.)
     DD   = two-digit day of month (01 through 31)
     hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
     mm   = two digits of minute (00 through 59)
     ss   = two digits of second (00 through 59)
     s    = one or more digits representing a decimal fraction of a second
     TZD  = time zone designator (Z or +hh:mm or -hh:mm)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50216335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档