Spring REST API中Timestamp字段返回值自动减2小时求助
解决Spring REST API中Timestamp返回时区偏移问题
这个问题我之前也碰到过,本质是时区和Jackson序列化规则导致的,咱们一步步拆解解决:
问题根源
你看到的2019-09-03T22:00:00Z是UTC时区的ISO 8601格式(Z代表UTC),而你预期的2019-09-04 00:00:00.000是UTC+2时区的本地时间格式。Java的Timestamp本身存储的是UTC时间戳,不带时区信息,Spring默认用Jackson序列化时,会把它转成UTC的标准格式,所以看起来像是少了2小时,其实是时区转换的显示问题,不是时间值本身错误。修改电脑系统时间没用,因为Java程序的时区配置(或Jackson的序列化规则)才是决定显示的关键。
解决方案
方案1:全局配置Jackson的时区和日期格式
如果希望所有接口的日期类型都按统一格式返回,可以在Spring中添加全局Jackson配置:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.text.SimpleDateFormat; import java.util.TimeZone; @Configuration public class JacksonGlobalConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); // 设置你需要的时区(这里是UTC+2,对应你差2小时的场景) mapper.setTimeZone(TimeZone.getTimeZone("GMT+2")); // 指定日期序列化格式,和你的预期格式一致 mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")); // 注册Java 8时间模块(如果用JDK8+的时间类型,比如LocalDateTime,这个很必要;用Timestamp也可以加上) mapper.registerModule(new JavaTimeModule()); // 关闭默认的日期转时间戳功能 mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; } }
方案2:单独给DTO字段加注解配置
如果只想针对ActionCustomDto的日期字段修改格式,直接在字段上用Jackson的@JsonFormat注解:
import com.fasterxml.jackson.annotation.JsonFormat; import java.sql.Timestamp; public class ActionCustomDto { private String actionDescription; // 指定格式、时区,强制转成字符串输出 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+2") private Timestamp startDate; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+2") private Timestamp dueDate; // 其他字段和对应的getter/setter... }
方案3:检查数据库连接的时区配置
还要确认数据库存储和读取时的时区是否正确,比如MySQL的话,可以在JDBC URL里明确指定时区,避免驱动自动转换:
jdbc:mysql://your-db-host:3306/your-db-name?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B2&useLegacyDatetimeCode=false
验证效果
配置完成后,重启服务再调用接口,就能得到你预期的2019-09-04 00:00:00.000格式的日期了。
内容的提问来源于stack exchange,提问作者Mohd Salim
相关产品推荐
相关产品推荐

