Spring RedisTemplate:将多个模型类序列化为JSON。需要使用多个 RedisTemplate?

2022-09-01 23:24:52

我正在使用Spring Redis支持来保存Redis中的对象。

我有几个处理不同模型类的DAO:

例如,保存/检索 的对象,保存/检索 的对象。ShopperHistoryDaoShopperHistoryModelShopperItemHistoryDaoItemHistoryModel

我想使用来序列化/反序列化我的对象到/从json。JacksonJsonRedisSerializer

但是在JacksonJsonRedisSerializer的构造器中,它需要一个特定的模型类。

JacksonJsonRedisSerializer(Class<T> type)

这是否意味着,我必须为每个不同的模型类单独配置,并在适当的DAO实现中使用它们?RedisTemplates

像这样:

<bean id="redisTemplateForShopperHistoryModel" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
    <property name="valueSerializer">
        <bean id="redisJsonSerializer" 
                        class="org.springframework.data.redis.serializer.JacksonJsonRedisSerializer">
            <constructor-arg type="java.lang.Class" value="ShopperHistoryModel.class"/>
        </bean>   
    </property>
</bean>


<bean id="redisTemplateForItemHistoryModel" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
    <property name="valueSerializer">
        <bean id="redisJsonSerializer" 
                        class="org.springframework.data.redis.serializer.JacksonJsonRedisSerializer">
            <constructor-arg type="java.lang.Class" value="ItemHistoryModel.class"/>
        </bean>   
    </property>
</bean>

答案 1

GenericJackson2JsonRedisSerializer 应该完成这项工作

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());                                           
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }

这会将@Class属性添加到 JSON 以了解类型,这有助于 Jackson 反序列化,因此无需在配置类上显式映射模型。

"{\"@class\":\"com.prnv.model.WhitePaper\",\"title\":\"Hey\",\"author\":{\"@class\":\"com.prnv.model.Author\",\"name\":\"Hello\"},\"description\":\"Description\"}"

在服务中,您可以使用以下命令缓存模型

    @Cacheable(value = "whitePaper", key = "#title")
    public WhitePaper findWhitePaperByTitle(String title) 
    {
        WhitePaper whitePaper = repository.findByTitle(title);
        return whitePaper;
    }

查看此文章: http://blog.pranavek.com/2016/12/25/integrating-redis-with-spring-application


答案 2

是的,RedisTemplate 似乎设计为具有值序列化程序的单个实例。

我打算建议一个可能的解决方法,其中包含内部序列化程序的映射,以便您可以使用一个可以处理多种类型的序列化程序 - 但是由于不提供诸如(如Spring MVC中的HTTP MessageConverters所具有的)这样的方法,这似乎是不可能的。RedisSerializerRedisTemplateRedisSerializerboolean canDeserialize(..)

因此,您似乎被困在拥有多个实例中。RedisTemplate