java中使用RedisTemplate读取数据异常 Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (byte[])"
java中使用RedisTemplate读取数据异常 Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (byte[])"
报错:
Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class'
at [Source: (byte[])"{"name":"测试","phone":"123","idCard":"12345","channelCode":"0"}"; line: 1, column: 66]
原代码:
@Autowired
private RedisTemplate<String, String> redisTemplate;
redisTemplate.opsForValue().set(token, JSONUtil.toJsonStr(currentUserInfo), tokenExpireTime, TimeUnit.SECONDS);
String userInfoRaw = redisTemplate.opsForValue().get(token);
错误原因:
redis存储对象时会多存一个@class,用于标注对象属性,再次读取时根据@class来反序列化对象。
但我调用redis存储时用了hutool的JSONUtil.toJsonStr来序列化对象,这个工具类在把对象转化为json字符串时会丢失@class信息,造成redis可以存储,不能读取的bug。
解决方法:
直接储存对象,让redis自己来序列化。
或者使用能保留@class信息的工具来序列化对象。
或者在读取时以字符串/map形式读取,再自己解析一下。
修改后代码:
@Autowired
private RedisTemplate<String, Object> redisTemplate;
redisTemplate.opsForValue().set(token, currentUserInfo, tokenExpireTime, TimeUnit.SECONDS);
Object userInfoRaw = redisTemplate.opsForValue().get(token);
再存一下解决redis中localDateTime类型参数反序列化错误的方法
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
// LocalDatetime序列化
JavaTimeModule timeModule = new JavaTimeModule();
timeModule.addDeserializer(LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
timeModule.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(timeModule);
// 设置键key的序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// 设置值value的序列化方式
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}

浙公网安备 33010602011771号