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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21672245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:01:02  来源:igfitidea点击:

Spring RedisTemplate : Serialise multiple Model classes into JSON.Need to use Multiple RedisTemplates?

javajsonspringserializationredis

提问by Ashika Umanga Umagiliya

I am using Spring Redis support to save my objects in Redis.

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

I have several DAOs which handle different Model classes:

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

For example, ShopperHistoryDaosave/retrieve objects of ShopperHistoryModel, ShopperItemHistoryDaosave/retrieve objects of ItemHistoryModel.

例如,ShopperHistoryDao保存/检索 的对象ShopperHistoryModelShopperItemHistoryDao保存/检索 的对象ItemHistoryModel

I want to use HymansonJsonRedisSerializerto serialise/deserialize my objects to/from json.

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

But in the constructor of HymansonJsonRedisSerializer, it takes one specific Model class.

但是在 HymansonJsonRedisSerializer 的构造函数中,它需要一个特定的 Model 类。

HymansonJsonRedisSerializer(Class<T> type)

Does that mean, I have to configure separate RedisTemplatesfor each different Model class and use them in appropriate DAO implementation?

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

Something like:

就像是:

<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.HymansonJsonRedisSerializer">
            <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.HymansonJsonRedisSerializer">
            <constructor-arg type="java.lang.Class" value="ItemHistoryModel.class"/>
        </bean>   
    </property>
</bean>

回答by matt b

Yes, the RedisTemplateseems to be designed to have a single instance of the value serializer.

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

I was going to suggest the possible workaround of having a RedisSerializerwhich contains a Map of inner serializers so you can use one RedisTemplatewith a serializer that can handle multiple types - but since RedisSerializerdoes not offer methods like boolean canDeserialize(..)(as the HTTP MessageConverters in Spring MVC have) this doesn't seem possible.

我打算建议一个可能的解决方法,RedisSerializer它包含一个内部序列化器的 Map,这样你就可以将一个RedisTemplate与一个可以处理多种类型的序列化器一起使用 - 但因为RedisSerializer不提供类似的方法boolean canDeserialize(..)(如 Spring MVC 中的 HTTP MessageConverters 有)这个似乎不可能。

So it seems that you are stuck with having multiple RedisTemplateinstances.

因此,您似乎坚持拥有多个RedisTemplate实例。

回答by Zeta

A bit of old thread, but you can do something like this:

有点旧线程,但你可以做这样的事情:

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

Then in your Java class

然后在你的 Java 类中

@Autowire
private RedisTemplate redisTemplate;

public void save(Model model) {
    ObjectMapper obmap = new ObjectMapper();
    redisTemplate.opsForHash().putAll(mode.getId(), obmap.convertValue(model, Map.class));
}

回答by Pranav

GenericHymanson2JsonRedisSerializershould do the job

GenericHymanson2JsonRedisSerializer应该完成这项工作

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

This will add @Classproperty to the JSON to understand the type, which helps Hymanson to deserialize, so no need to explicitly map the model on the configuration class.

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

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

In the service you can cache the model using

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

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

Check this article: http://blog.pranavek.com/2016/12/25/integrating-redis-with-spring-application

检查这篇文章:http: //blog.pranavek.com/2016/12/25/integrating-redis-with-spring-application