You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过RedisTemplate的getValue操作正确获取CustomObject对象列表?

RedisTemplate获取对象列表返回LinkedHashMap的解决方法

问题根源

你遇到的问题是因为GenericJackson2JsonRedisSerializer默认序列化集合时,不会保存泛型类型信息,反序列化时无法识别元素的具体类型,只能将其转为LinkedHashMap。同时原代码中的两处写法加剧了这个问题:

  • RedisTemplate泛型定义为RedisTemplate<String, List<Object>>,无法正确传递集合元素的泛型信息
  • 保存时通过Arrays.asList(customObjects.toArray())将List<CustomObject>转为List<Object>,进一步丢失了类型元数据

解决方案

方案1:使用TypeReference指定反序列化类型

修改RedisTemplate泛型和DAO方法,在获取值时明确指定目标泛型类型:

public class RedisDao {
    private final RedisTemplate<String, Object> redisTemplate;

    public RedisDao(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void saveCustomObjects(List<CustomObject> customObjects, String key) {
        // 直接保存原List<CustomObject>,无需转换
        redisTemplate.opsForValue().set(key, customObjects);
    }

    public List<CustomObject> getCustomObjects(String key) {
        // 通过TypeReference明确反序列化的目标类型
        return redisTemplate.opsForValue().get(key, new TypeReference<List<CustomObject>>() {});
    }
}

方案2:配置Jackson保存类型信息

通过修改GenericJackson2JsonRedisSerializer的ObjectMapper,让序列化时自动保存类型信息,这样反序列化时无需手动指定类型:

// RedisTemplate配置代码
ObjectMapper objectMapper = new ObjectMapper();
// 开启默认类型识别,为非final类型添加类型信息
objectMapper.activateDefaultTyping(
    LaissezFaireSubTypeValidator.instance,
    ObjectMapper.DefaultTyping.NON_FINAL,
    JsonTypeInfo.As.PROPERTY
);

redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
redisTemplate.afterPropertiesSet();

此时DAO方法可以简化为:

public class RedisDao {
    private final RedisTemplate<String, List<CustomObject>> redisTemplate;

    public void saveCustomObjects(List<CustomObject> customObjects, String key) {
        redisTemplate.opsForValue().set(key, customObjects);
    }

    public List<CustomObject> getCustomObjects(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}

注意事项

  • 方案1无需修改序列化配置,适合临时场景;方案2一劳永逸,但会在序列化的JSON中增加类型字段(如@class),占用少量额外空间
  • 避免将集合类型直接作为RedisTemplate的泛型参数,推荐使用RedisTemplate<String, Object>,通过TypeReference灵活指定反序列化类型

内容的提问来源于stack exchange,提问作者Robert S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 17:08:19