使用RedisTemplate从Redis获取Set值

19

我能够使用 JedisRedis 中检索数据:

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

但是当我试图使用Spring的RedisTemplate时,我无法获取任何数据。我的数据以Set的形式存储在Redis中。

      // 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 "";
    }

有人能告诉我我错过了什么吗?

编辑:我的 RedisTemplate 的 XML 配置。

 <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个回答

40

简而言之

您需要配置序列化器。

解释

Redis模板使用序列化器来处理键、值和哈希键/值。序列化器用于将Java输入转换为存储在Redis中的表示形式。如果您没有进行任何配置,则序列化器默认为JdkSerializationRedisSerializer。因此,如果您在Java代码中请求一个键key,序列化器会将其转换为

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

同时,Spring Data 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"

正如您所见,String和Date被序列化为代表Java序列化对象的一些疯狂字节。

您的代码表明您想要存储基于字符串的键和值。只需在RedisTemplate中设置StringRedisSerializer即可。

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.RELEASE和jedis 2.6.2来验证您问题的结果。希望对您有所帮助,Mark

更多阅读:


我遇到了以下错误:在ServletContext资源[/WEB-INF/root-context.xml]中定义的名为'listener'的bean创建失败:调用init方法失败;嵌套异常是java.lang.IllegalArgumentException:需要RedisConnectionFactory。 - Zeeshan
使用Java配置工作正常。不知道为什么在XML配置中出现错误。谢谢 - Zeeshan
1
我已经从XML示例中删除了connectionFactory。我更新了代码,现在它可以工作了。感谢你的提示。 - mp911de

1
你可以使用Redisson更轻松地完成它:
public static void main(String[] args) {
    Config conf = new Config();
    conf.useSingleServer().setAddress(redisURL);

    RedissonClient redisson = Redisson.create(conf);
    RSet<String> set = redisson.getSet("key")
    for (String s : set.readAllValues()) {
        System.out.println(s);
    }
    redisson.shutdown();
}

这个框架处理序列化并与连接一起工作,因此您不需要每次都去处理它。使用Redis就像以前处理Java对象(Set、Map、List…)一样。它还支持许多流行的编解码器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接