Java第十二篇:关于RedisTemplate取String类型的value转对象出现的SerializationException问题解决

问题背景

  • SpringBoot项目,整合了spring-boot-starter-data-redis
  • 通过配置RedisTemplate来进行redis Key的增删查改操作
  • 将对象存入redis成功(对象中还包含对象)
    Java第十二篇:关于RedisTemplate取String类型的value转对象出现的SerializationException问题解决_第1张图片

问题是:但是取出来的时候转成AuthInfo对象报错了!!!
异常如下:

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `com.zt.space.security.vo.JwtUser` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])"["com.zt.}]"; line: 1, column: 331] (through reference chain: com.zt.space.security.vo.AuthInfo["jwtUser"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.zt.space.security.vo.JwtUser` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])")
	at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:75)
...

原因

序列化原因!!!

解决方案

中途经历许多波折和探索,就不一一叙述了,直接上解决方案

第一步

先查看自己的RedisTemplate配置,有没有手动设置了序列化?
我也是参考另一篇博客的解答:Redis使用过程出现类型转换异常问题- 20190220
一看我自己的配置如下(网上照搬的。由此可见网上的东西坑货还是挺多的):

	@Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();

        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper om = new ObjectMapper();

        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key采用String的序列化方式

        template.setKeySerializer(stringRedisSerializer);

        // hash的key也采用String的序列化方式

        template.setHashKeySerializer(stringRedisSerializer);

        // value序列化方式采用jackson

        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的value序列化方式采用jackson

        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();

        return template;

    }

根据那篇博文的解释:RedisTemplate已经默认使用序列化了,我去看了下源码,还真是的,可能是以前的老版本不是。
所以根本不需要自己在手动设置,修改如下:

	@Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();

        template.setConnectionFactory(factory);

        return template;

    }

这个时候已经存取正常了
但是,人生总是会有意外惊喜
我去RDM中查看存的数据情况,如下:

Java第十二篇:关于RedisTemplate取String类型的value转对象出现的SerializationException问题解决_第2张图片

完全无法查看json,感觉是乱码,但是实际上你通过java代码取出来的是正常的,只是无法通过RDM查看
初步估计是序列化的格式不对

你可能感兴趣的:(java,redis,数据库)