web-dev-qa-db-ja.com

Spring RedisTemplate:複数のモデルクラスをJSONにシリアル化します。複数のRedisTemplatesを使用する必要がありますか?

Spring Redisサポートを使用してオブジェクトをRedisに保存しています。

さまざまなモデルクラスを処理する複数のDAOがあります。

たとえば、ShopperHistoryDaoの保存/取得オブジェクトShopperHistoryModelShopperItemHistoryDaoの保存/取得オブジェクトItemHistoryModel

JacksonJsonRedisSerializerを使用して、jsonとの間でオブジェクトをシリアル化/逆シリアル化したいと思います。

しかし、JacksonJsonRedisSerializerのコンストラクターでは、1つの特定のModelクラスを取ります。

JacksonJsonRedisSerializer(Class<T> type)

つまり、異なるModelクラスごとに個別のRedisTemplatesを構成し、適切なDAO実装でそれらを使用する必要があるということですか?

何かのようなもの:

<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>

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

18
Pranav

はい、 RedisTemplate は値シリアライザの単一のインスタンスを持つように設計されているようです。

複数のタイプを処理できるシリアライザで1つのRedisSerializerを使用できるように、内部シリアライザのマップを含むRedisTemplateを使用することで可能な回避策を提案しましたが、RedisSerializerboolean canDeserialize(..)のようなメソッドを提供していません(Spring MVCのHTTP MessageConvertersが持っているように)これは不可能のようです。

したがって、複数のRedisTemplateインスタンスがあることに行き詰まっているようです。

4
matt b

少し古いスレッドですが、次のようなことができます:

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

次に、Javaクラス

@Autowire
private RedisTemplate redisTemplate;

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