Gson反序列化java.sql.Date/Time时日期时间值不符问题
问题原因分析
1. 自定义反序列化适配器格式处理错误
你注册的java.sql.Date和java.sql.Time适配器大概率没有正确匹配请求传入的字符串格式:
- 针对
java.sql.Date,如果适配器未指定明确的yyyy-MM-dd格式解析,而是依赖系统默认格式,会导致解析失败,最终返回异常的默认日期(比如纪元日期偏移后出现的2021-12-26) - 针对
java.sql.Time,若未按HH:mm:ss格式解析,会直接返回默认的00:00:00
比如错误的适配器写法:
// 错误示例:未指定固定格式,依赖系统默认导致解析异常 public class SqlDateAdapter implements JsonDeserializer<java.sql.Date> { @Override public java.sql.Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return new java.sql.Date(new SimpleDateFormat().parse(json.getAsString()).getTime()); } }
2. GET请求参数传递方式错误
GET请求的JSON参数若通过请求体传递,Tomcat默认会忽略GET请求的请求体内容,此时Gson解析的是初始化的空对象,而非你传入的参数,自然出现默认日期时间值。
3. 实体类字段映射不匹配
检查DietDiary类的字段:
- 字段名称是否和JSON键名完全一致(比如JSON是
createDate,类中写成createdDate) - 私有字段是否未配置Gson的私有字段访问权限,或缺少对应的
getter/setter
4. Gson适配器注册错误
可能存在适配器注册类型错误的情况:比如把java.sql.Date的适配器注册给了java.util.Date,或者重新创建了未注册适配器的Gson实例,导致自定义解析逻辑未生效。
错误的注册示例:
// 错误示例:注册util.Date适配器而非sql.Date Gson gson = new GsonBuilder() .registerTypeAdapter(java.util.Date.class, new SqlDateAdapter()) .create();
排查建议
- 先打印后端接收到的原始JSON字符串,确认参数是否正确传递
- 修改自定义适配器,指定明确的解析格式:
// 正确的Date适配器示例 public class SqlDateAdapter implements JsonDeserializer<java.sql.Date> { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); static { DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); // 按需设置时区 } @Override public java.sql.Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { return new java.sql.Date(DATE_FORMAT.parse(json.getAsString()).getTime()); } catch (ParseException e) { throw new JsonParseException(e); } } }
- 将GET请求改为POST请求传递JSON参数,或把日期时间参数编码后放在URL的query中
- 检查
DietDiary类的字段命名和Gson配置,确保字段能被正确映射
内容的提问来源于stack exchange,提问作者黃奕捷
相关产品推荐
相关产品推荐

