redisTemplate取对象时反序列化失败

2022-07-21 10:37:55

错误:

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized field

注意:反序列化时要保证实体对象有一个无参构造函数,否则反序列化也会失败

json序列化是根据set和get方法来序列化字段的,如果方法正好有set和get开头但没有对应field,那么反序列化就会失败。可以在实体类加上注解@JsonIgnoreProperties(ignoreUnknown = true)忽略实体中没有对应的json的key值,或者在set方法上加上@JsonIgnore注解,如果是用mongoDb数据库,第二种方法那么就不大适用了,总不能去ObjectId类操作,这是修改别人的源代码。

以下是redisTemplate在springboot2.x里面存取对象的配置,等同于第一种方法

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        //Use Jackson 2Json RedisSerializer to serialize and deserialize the value of redis (default JDK serialization)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//将类名称序列化到json串中,去掉会导致得出来的的是LinkedHashMap对象,直接转换实体对象会失败
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        //设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        //Use String RedisSerializer to serialize and deserialize the key value of redis
        RedisSerializer redisSerializer = new StringRedisSerializer();
        //key
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);
        //value
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;

    }

}

application.properties文件添加如下,springboot2.x连接池用的是lettuce

spring.redis.host=localhost
spring.redis.password=
# 连接超时时间(毫秒)
spring.redis.timeout=3000ms
# Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0
spring.redis.database=0
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0

添加数据进redis

    @Test
    public void testRedis() {
        Headset headset = new Headset();
        redisTemplate.opsForValue().set("test:123", headset);
        System.out.println(redisTemplate.opsForValue().get("test:123"));
    }
  • 作者:shuangyueliao
  • 原文链接:https://shuangyueliao.blog.csdn.net/article/details/95120342
    更新时间:2022-07-21 10:37:55