JEE7升级至Jakarta EE10后,如何恢复java.sql.Timestamp的JSON整数格式?
解决Jakarta EE 10中java.sql.Timestamp序列化回时间戳整数的问题
升级到Jakarta EE 10后,默认JSON序列化实现(Yasson,JSON-B的参考实现)对java.sql.Timestamp的处理规则发生了变化,从原本的时间戳整数转为ISO格式字符串。以下是几种恢复原格式的简便方案:
1. 全局配置JSON-B统一处理Timestamp
通过自定义JSON-B序列化器并全局注册,让所有Timestamp字段自动序列化为时间戳整数:
import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.Produces; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import java.sql.Timestamp; @ApplicationScoped public class GlobalJsonbProducer { @Produces public Jsonb createJsonb() { JsonbConfig config = new JsonbConfig() .withSerializer(new TimestampToLongSerializer()); return JsonbBuilder.create(config); } private static class TimestampToLongSerializer implements jakarta.json.bind.serializer.JsonbSerializer<Timestamp> { @Override public void serialize(Timestamp value, jakarta.json.bind.serializer.SerializationContext ctx, jakarta.json.stream.JsonGenerator generator) { if (value == null) { generator.writeNull(); return; } generator.write(value.getTime()); } } }
该类会被JAX-RS自动识别,全局应用到所有JSON序列化场景,无需修改业务DTO代码。
2. 局部字段注解(针对个别字段)
如果仅需特定Timestamp字段使用时间戳格式,可在DTO字段上添加序列化注解:
import jakarta.json.bind.annotation.JsonbTypeSerializer; import java.sql.Timestamp; public class SomeDto { // 仅该字段序列化为时间戳整数 @JsonbTypeSerializer(TimestampToLongSerializer.class) private Timestamp timestamp; // 其他字段、getter/setter省略 } // 序列化器类同方法1中的TimestampToLongSerializer
3. 切换回Jackson作为JSON处理器
若旧版JEE7使用的是Jackson,可直接引入Jakarta EE兼容的Jackson JAX-RS提供者,替换默认的JSON-B:
添加Maven依赖:
<dependency> <groupId>com.fasterxml.jackson.jakarta.rs</groupId> <artifactId>jackson-jakarta-rs-json-provider</artifactId> <version>2.15.2</version> </dependency>
Jackson默认会将java.sql.Timestamp序列化为时间戳整数,无需额外配置即可恢复原有行为。
最优方案选择
- 全局统一需求:优先选方法1,零业务代码侵入;
- 原有技术栈为Jackson:选方法3,完全复用旧序列化逻辑;
- 局部字段特殊处理:选方法2,灵活控制单个字段行为。
内容的提问来源于stack exchange,提问作者Arto Oksanen
相关产品推荐
相关产品推荐

