You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot无法解析OffsetDateTime作为REST服务参数问题

Spring Boot 3中OffsetDateTime请求参数转换失败

环境信息

Springboot 3.0.3
OpenJdk-17

问题详情

定义了一个接收OffsetDateTime类型请求参数的REST接口:

@GetMapping("/transaction/search/bydate")
public String searchTransactions(
        @RequestParam("fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime fromDate)
{
    logger.debug("Request received!");
    return "Received " + fromDate.toString();
}

Gradle依赖配置:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

调用接口时触发400错误,调用命令:

curl localhost:8080/transaction/search/another?fromDate=2022-05-09T01:30:00.000-5:00

错误响应:

{
  "timestamp": "2023-02-23T21:44:12.191+00:00",
  "status": 400,
  "error": "Bad Request",
  "path": "/transaction/search/another"
}

日志中的错误堆栈:

s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to  com.example.demo.RestController#searchTransactions(Optional, OffsetDateTime)
o.s.beans.TypeConverterDelegate          : Field [2022-05-09T01:30:00.000-5:00] isn't an enum value
java.lang.NoSuchFieldException: 2022-05-09T01:30:00.000-5:00
    at java.base/java.lang.Class.getField(Class.java:2117) ~[na:na]
    at org.springframework.beans.TypeConverterDelegate.attemptToConvertStringToEnum(TypeConverterDelegate.java:308) ~[spring-beans-6.0.5.jar:6.0.5]
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:215) ~[spring-beans-6.0.5.jar:6.0.5]
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73) ~[spring-beans-6.0.5.jar:6.0.5]
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53) ~[spring-beans-6.0.5.jar:6.0.5]
    at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:729) ~[spring-context-6.0.5.jar:6.0.5]
....

注:将参数改为LocalDateTime并去掉请求中的偏移量后,接口可正常运行。

已尝试的无效解决方案

  • 自定义ObjectMapper配置类
@Configuration
public class JsonConfiguration {

 private static final ObjectMapper OBJECT_MAPPER =
       new ObjectMapper().registerModule(new JavaTimeModule()) 
     .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
     .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
     .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

 @Bean
 @Primary
 public static ObjectMapper getObjectMapper() {
     return OBJECT_MAPPER;
 }
}
  • 继承WebMvcConfigurationSupport添加自定义转换服务
@Bean
@Override
public FormattingConversionService mvcConversionService() {
    DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);

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

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

    return conversionService;
}
  • 配置Jackson2ObjectMapperBuilderCustomizer
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

    return builder -> {

        // formatter
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter =  DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // deserializers
        builder.deserializers(new OffsetDateTimeDeserializer());

        // serializers
        builder.serializers(new OffsetDateTimeSerializer());
    };
}

备选思路

如果上述方案均无效,考虑将参数类型改为String,在方法内部手动验证并转换为OffsetDateTime。


内容的提问来源于stack exchange,提问作者Sannu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 23:18:33