Spring Boot全局配置Instant序列化为秒级时间戳方案咨询
全局配置Spring Boot将Instant序列化为秒级时间戳
你提到想要不用逐个给DTO的Instant字段加@JsonSerialize,而是通过一处配置全局实现秒级时间戳的序列化,这个需求完全可以通过自定义Jackson模块并全局注册来实现,下面是具体的方案:
步骤1:保留你的自定义序列化器
你已经写好的CustomInstantSerializer完全可以直接用,它负责把Instant转换成秒级的数值:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; import java.time.Instant; public class CustomInstantSerializer extends StdSerializer<Instant> { public CustomInstantSerializer() { this(null); } public CustomInstantSerializer(Class<Instant> t) { super(t); } @Override public void serialize(Instant value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeNumber(value.getEpochSecond()); } }
步骤2:全局注册序列化器
通过Spring配置类,把这个序列化器注册到Jackson的ObjectMapper中,这样所有Instant类型的字段都会自动使用这个序列化规则,不需要额外注解:
方式一:直接定制ObjectMapper Bean
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.time.Instant; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule instantModule = new SimpleModule(); // 注册自定义序列化器 instantModule.addSerializer(Instant.class, new CustomInstantSerializer()); // 如果需要支持反序列化(前端传秒级数值转Instant),可以同时注册反序列化器 // instantModule.addDeserializer(Instant.class, new CustomInstantDeserializer()); objectMapper.registerModule(instantModule); // 之前的WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS配置可以移除了,因为我们用自定义序列化器完全接管了 // objectMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS); return objectMapper; } }
方式二:用Jackson2ObjectMapperBuilder(更贴合Spring Boot自动配置)
如果想兼容Spring Boot的默认Jackson配置,推荐用这种方式:
import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.time.Instant; @Configuration public class JacksonConfig { @Bean public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() { return new Jackson2ObjectMapperBuilder() .modulesToInstall(new SimpleModule() {{ addSerializer(Instant.class, new CustomInstantSerializer()); // 按需添加反序列化器 // addDeserializer(Instant.class, new CustomInstantDeserializer()); }}); } }
可选:添加反序列化支持(如果需要)
如果前端会传秒级数值过来,需要转换成Instant,可以写一个对应的反序列化器并注册:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.time.Instant; public class CustomInstantDeserializer extends StdDeserializer<Instant> { public CustomInstantDeserializer() { this(null); } public CustomInstantDeserializer(Class<?> vc) { super(vc); } @Override public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { long epochSecond = p.getLongValue(); return Instant.ofEpochSecond(epochSecond); } }
效果验证
配置完成后,所有DTO中的Instant字段都会自动序列化为秒级整数,比如Instant.now()会输出类似1718000000这样的数值,完全符合你的需求,而且不需要在任何字段上添加@JsonSerialize注解。
内容的提问来源于stack exchange,提问作者Aleksei
相关产品推荐
相关产品推荐

