如何在Jackson2JsonRedisSerializer中反序列化java.time.Instant
Java 8 Instant类型Redis反序列化问题解决
问题背景
使用Jackson2JsonRedisSerializer操作Redis时,Aircraft类中的Instant类型字段lastSeenTime反序列化失败,报错提示缺少JSR310模块,但已添加对应Maven依赖。
配置代码:
@Bean public RedisOperations<String , Aircraft> redisOperations(RedisConnectionFactory factory){ Jackson2JsonRedisSerializer<Aircraft> serializer = new Jackson2JsonRedisSerializer<Aircraft>(Aircraft.class); RedisTemplate<String, Aircraft> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setDefaultSerializer(serializer); template.setKeySerializer(new StringRedisSerializer()); return template; }
Aircraft字段定义:
@JsonProperty("last_seen_time") private Instant lastSeenTime;
错误信息:
默认不支持Java 8日期/时间类型
java.time.Instant:请添加模块"com.fasterxml.jackson.datatype:jackson-datatype-jsr310"以启用处理(引用链:com.example.chapter6.sburredis.Aircraft["last_seen_time"])
已添加的Maven依赖:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.14.1</version> </dependency>
对应JSON数据:
{ "aircraft": [ { "id": 108, "callsign": "AMF4263", "squawk": "4136", "reg": "N49UC", "flightno": "", "route": "LAN-DFW", "type": "B190", "category": "A1", "altitude": 20000, "heading": 235, "speed": 248, "lat": 38.865905, "lon": -90.429382, "barometer": 0, "vert_rate": 0, "selected_altitude": 0, "polar_distance": 12.99378, "polar_bearing": 345.393951, "is_adsb": true, "is_on_ground": false, "last_seen_time": 1672576769, "pos_update_time": 1672576769, "bds40_seen_time": null } ] }
解决方法
1. 手动配置ObjectMapper并注册JavaTimeModule
Jackson2JsonRedisSerializer默认使用的ObjectMapper不会自动注册JSR310模块,需要手动配置:
@Bean public RedisOperations<String, Aircraft> redisOperations(RedisConnectionFactory factory) { Jackson2JsonRedisSerializer<Aircraft> serializer = new Jackson2JsonRedisSerializer<>(Aircraft.class); ObjectMapper objectMapper = new ObjectMapper(); // 注册Java 8时间模块 objectMapper.registerModule(new JavaTimeModule()); // 适配秒级时间戳:关闭纳秒级时间戳解析/序列化 objectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false); // 可选:如果需要序列化时输出ISO格式而非时间戳,可开启下面配置 // objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); serializer.setObjectMapper(objectMapper); RedisTemplate<String, Aircraft> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setDefaultSerializer(serializer); template.setKeySerializer(new StringRedisSerializer()); return template; }
2. 字段级注解配置(可选)
如果不想全局配置,可在Instant字段上添加注解指定时间格式:
@JsonProperty("last_seen_time") @JsonFormat(shape = JsonFormat.Shape.NUMBER, timezone = "UTC") private Instant lastSeenTime;
核心原因
- Jackson的
JavaTimeModule不会自动关联到Jackson2JsonRedisSerializer的ObjectMapper实例,必须手动注册。 - 你的JSON中时间戳是秒级,而Jackson默认处理Instant时按毫秒级解析,因此需要关闭
READ_DATE_TIMESTAMPS_AS_NANOSECONDS配置,确保秒级时间戳能正确转换为Instant对象。
内容的提问来源于stack exchange,提问作者Hamza
相关产品推荐
相关产品推荐

