Spring RedisTemplate: Сериализовать несколько классов модели в JSON. Нужно использовать несколько RedisTemplates?
Я использую Spring поддержку Redis для сохранения моих объектов в Redis.
У меня есть несколько DAO, которые обрабатывают разные классы Model:
например: "ShopperHistoryDao", который будет сохранять/извлекать объекты "ShopperHistoryModel",
"ShopperItemHistoryDao", который будет обрабатывать объекты "ItemHistoryModel"
Я хочу использовать "JacksonJsonRedisSerializer" для сериализации/десериализации моих объектов в/из json.
Но в конструкторе JacksonJsonRedisSerializer он принимает один конкретный класс модели.
JacksonJsonRedisSerializer(Class<T> type)
Означает ли это, что мне нужно настроить отдельные 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>
Ответы
Ответ 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, чтобы понять тип, что поможет Джексону десериализоваться, поэтому нет необходимости явно отображать модель в классе конфигурации.
"{\"@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
, похоже, предназначен для того, чтобы иметь один экземпляр сериализатора значений.
Я собирался предложить возможное обходное решение с RedisSerializer
, которое содержит карту внутренних сериализаторов, поэтому вы можете использовать один RedisTemplate
с сериализатором, который может обрабатывать несколько типов, но так как RedisSerializer
не предлагает методы например boolean canDeserialize(..)
(поскольку HTTP MessageConverters в Spring MVC есть) это не представляется возможным.
Итак, кажется, что вы застряли в наличии нескольких экземпляров RedisTemplate
.
Ответ 3
Немного старого потока, но вы можете сделать что-то вроде этого:
<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));
}
Ответ 4
@Bean
public RedisTemplate<String, Object> redisTemplate() {
final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(jedisConnectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
template.afterPropertiesSet();
return template;
}