web-dev-qa-db-fra.com

Obtenir la valeur Set de Redis à l'aide de RedisTemplate

Je suis capable de récupérer les valeurs de Redis en utilisant 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();
    }

Mais lorsque j'essaie d'utiliser la variable RedisTemplate de Spring, je ne reçois aucune donnée. Mes données sont stockées dans Redis sous la forme 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 "";
    }

Est-ce que quelqu'un peut me signaler ce qui me manque?

EDIT: Ma configuration xml pour 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" />
12
Zeeshan

En bref

Vous devez configurer les sérialiseurs.

Explication

Le modèle Redis utilise des sérialiseurs pour les clés, les valeurs et les clés/valeurs de hachage. Les sérialiseurs sont utilisés pour convertir les entrées Java dans la représentation stockée dans Redis. Si vous ne configurez rien, le sérialiseur a par défaut la valeur JdkSerializationRedisSerializer. Donc, si vous demandez une clé key dans votre code Java, le sérialiseur la convertit en

"\xac\xed\x00\x05t\x00\x03key"

spring Data Redis utilise ces octets comme clé pour interroger Redis.

Vous pouvez ajouter des données avec Spring Data Redis et les interroger à l'aide du redis-cli:

template.boundSetOps("myKey").add(new Date());

puis dans le 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"

Comme vous le voyez, la chaîne et la date sont sérialisées dans des octets loufoques qui représentent un objet sérialisé Java.

Votre code suggère que vous souhaitiez stocker des clés et des valeurs basées sur des chaînes. Il suffit de définir la StringRedisSerializer dans votre RedisTemplate

Configuration Java

redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());

Configuration 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"/>

Après avoir exécuté votre code, la sortie ressemble à ceci:

value
key
[value]

Spring Data Redis propose des sérialiseurs intéressants permettant l’échange de messages entre différents systèmes. Vous pouvez choisir parmi les sérialiseurs intégrés

  • JacksonJsonRedisSerializer
  • Jackson2JsonRedisSerializer
  • JdkSerializationRedisSerializer (par défaut)
  • OxmSerializer
  • GenericToStringSerializer

ou créez le vôtre.

J'ai utilisé Spring Data Redis 1.5.1.RELEASE et jedis 2.6.2 pour vérifier le résultat de votre question. HTH, Mark

Plus loin lu: 

24
mp911de

Vous pourriez le faire beaucoup plus facilement avec Redisson :

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();
}

Ce framewrok gère la sérialisation et fonctionne avec la connexion, vous n'avez donc pas besoin de la gérer à chaque fois. Travaillez avec Redis comme vous utilisiez des objets Java (Set, Map, List ...). Il prend également en charge de nombreux codecs populaires.

0
Nikita Koksharov