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

Spring Boot Post请求无法接收JSON请求体中的DateTime参数

解决Spring Boot Post请求中DateTime类型参数的反序列化问题

问题根源

你遇到的400错误是因为Gson默认会将Joda-Time的DateTime类型解析为对象,但请求体中传递的是字符串格式的日期,导致反序列化时抛出Expected BEGIN_OBJECT but was STRING异常。同时你使用的是Jackson的@JsonFormat、@JsonDeserialize注解,这些注解在Gson作为JSON处理器时不会生效。

解决方案

方案一:自定义Gson的DateTime类型适配器

如果项目需要继续使用Gson,需要为DateTime类型自定义反序列化逻辑:

  1. 创建Gson TypeAdapter处理字符串转DateTime
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.io.IOException;

public class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
    // 匹配请求体的日期格式,指定UTC时区
    private static final DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZoneUTC();

    @Override
    public void write(JsonWriter out, DateTime value) throws IOException {
        out.value(value == null ? null : FORMATTER.print(value));
    }

    @Override
    public DateTime read(JsonReader in) throws IOException {
        String dateStr = in.nextString();
        return dateStr == null || dateStr.isEmpty() ? null : FORMATTER.parseDateTime(dateStr);
    }
}
  1. 配置Spring Boot使用自定义Gson实例
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.joda.time.DateTime;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.GsonHttpMessageConverter;

@Configuration
public class GsonConfig {
    @Bean
    public GsonHttpMessageConverter gsonHttpMessageConverter() {
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
                .create();
        converter.setGson(gson);
        return converter;
    }
}

方案二:切换回Jackson(Spring Boot默认处理器)

如果没有强制使用Gson的需求,推荐使用Spring Boot默认的Jackson处理器,步骤如下:

  1. 添加Jackson处理Joda-Time的依赖(Maven)
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-joda</artifactId>
</dependency>
  1. 修正DTO类的注解
    移除无效的@DateTimeFormat(该注解用于表单参数,不适用JSON请求体),使用Jackson的Joda-Time专用反序列化器:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer;
import org.joda.time.DateTime;
import java.io.Serializable;

public class FilteredJobsDto implements Serializable {

    private String jobName;
    private Long createdBy;
    private String status = "submitted";
    private String tenantId;
   
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
    @JsonDeserialize(using = DateTimeDeserializer.class)
    private DateTime startDate;
    
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
    private DateTime endDate;

    // Getter、Setter 方法
}
  1. 确保项目未强制使用Gson
    检查application.properties或application.yml,移除如下配置(如果存在):
spring.http.converter.preferred-json-mapper=gson

验证

修改完成后,用原请求体测试接口,即可正常解析startDate参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:58:17