Получить установленное значение из Redis с помощью RedisTemplate
Я могу получить значения из Redis
используя Jedis
:
public static void main(String[] args) {
Jedis jedis = new Jedis(HOST, PORT);
jedis.connect();
Set<String> set = jedis.smembers(KEY);
for (String s : set) {
System.out.println(s);
}
jedis.disconnect();
jedis.close();
}
но когда я пытаюсь использовать весной RedisTemplate
, Я не получаю никаких данных. Мои данные хранятся в Redis
как Set
.
// inject the actual template
@Autowired
private RedisTemplate<String, Object> template;
// inject the template as SetOperations
@Resource(name="redisTemplate")
private SetOperations<String,String> setOps;
public String logHome() {
Set<String> set = setOps.members(KEY);
for(String str:set){
System.out.println(str); //EMPTY
}
Set<byte[]> keys = template.getConnectionFactory().getConnection().keys("*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext()){
byte[] data = (byte[])it.next();
System.out.println(new String(data, 0, data.length)); //KEYS are printed.
}
Set<Object> mySet = template.boundSetOps(KEY).members();
System.out.println(mySet); //EMPTY
return "";
}
может кто-нибудь, пожалуйста, укажите мне, что я пропустил?
EDIT: моя конфигурация xml для RedisTemplate.
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory"/>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="myhostname" p:port="6379" />
2 ответов
короче
вы должны настроить сериализаторами.
объяснение
шаблон Redis использует сериализаторы для ключей, значений и хэш-ключей/значений. Сериализаторы используются для преобразования входных данных Java в представление, которое хранится в Redis. Если вы ничего не настраиваете, сериализатор по умолчанию имеет значение JdkSerializationRedisSerializer
. Поэтому, если вы попросите ключ key
в вашем Java-коде сериализатор преобразует его в
"\xac\xed\x00\x05t\x00\x03key"
и данные по весны Redis использует эти байты в качестве ключа для запроса Redis.
вы можете добавить данные с помощью Spring Data Redis и запросить его с помощью redis-cli
:
template.boundSetOps("myKey").add(new Date());
а потом в redis-cli
127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x05myKey"
127.0.0.1:6379> SMEMBERS "\xac\xed\x00\x05t\x00\x05myKey"
1) "\xac\xed\x00\x05sr\x00\x0ejava.util.Datehj\x81\x01KYt\x19\x03\x00\x00xpw\b\x00\x00\x01N\xcf#\x9cHx"
как вы видите, строка и дата сериализуются в некоторые сумасшедшие байты, которые представляют собой сериализованный объект Java.
ваш код предполагает, что вы хотите хранить строковые ключи и значения. Просто установите StringRedisSerializer
в вашей RedisTemplate
настройки Java
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
настройки XML
<bean id="stringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory">
<property name="keySerializer" ref="stringSerializer"/>
<property name="valueSerializer" ref="stringSerializer"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="myhostname" p:port="6379"/>
вывод после запуска кода выглядит так:
value
key
[value]
Spring Data Redis имеет некоторые интересные сериализаторы, которые позволяют обмениваться сообщениями между различными системами. Вы можете выбрать любой из встроенных сериализаторы
- JacksonJsonRedisSerializer
- Jackson2JsonRedisSerializer
- JdkSerializationRedisSerializer (по умолчанию)
- OxmSerializer
- GenericToStringSerializer
или создать свой собственный.
я использовал Spring Data Redis 1.5.1.Отпустите и jedis 2.6.2, чтобы проверить результат вашего вопроса. ХТ, Марк
далее:
вы могли бы сделать это намного проще с Рэдиссон:
public static void main(String[] args) {
Config conf = new Config();
conf.useSingleServer().setAddress(host + ":" + port);
RedissonClient redisson = Redisson.create(conf);
RSet<String> set = redisson.getSet(KEY)
for (String s : set.readAllValues()) {
System.out.println(s);
}
redisson.shutdown();
}
этот framewrok обрабатывает сериализацию и работает с подключением, поэтому вам не нужно иметь дело с ним каждый раз. Работа с Redis, как вы работали с объектами Java (Set, Map, List ...). Он также поддерживает множество популярных кодеков.