【问题标题】:spring-data-redis redisTemplate Exceptionspring-data-redis redisTemplate 异常
【发布时间】:2013-06-18 07:14:10
【问题描述】:

调用get()方法时发生异常

这里是代码

@Service("RedisService")
public class RedisServiceImpl implements RedisService {

@Autowired
RedisTemplate<String, Long> redisTemplate;

@Override
public Long get(String key) {
    return redisTemplate.opsForValue().get(key);
}

@Override
public Long incrBy(String key, long increment) {
    return redisTemplate.opsForValue().increment(key, increment);
}

当我使用incrBy方法时,没有异常只有错误​​只有get方法





这是堆栈跟踪---

java.io.EOFException
    at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2280)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2749)
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:779)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
    at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:38)
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:58)
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:1)
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:40)
    at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:198)
    at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:50)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:162)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:133)
    at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:84)
    at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:42)
    at net.daum.air21.bot.common.service.RedisServiceImpl.get(RedisServiceImpl.java:29)
    at net.daum.air21.bot.user.service.SeraCoffeeServiceImpl.getCurrentCount(SeraCoffeeServiceImpl.java:41)

【问题讨论】:

    标签: spring redis jedis spring-data-redis


    【解决方案1】:

    默认情况下,RedisTemplate 使用 JdkSerializationRedisSerializer,所以如果你做了一个“设置”,它会让你的 Long 在 Redis 中看起来像这样:

    "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x00\x00\x00\x00\x04"
    

    IncrBy 有效,因为 Redis 总是从该操作返回 Long,因此 RedisTemplate 不会尝试反序列化结果。然而,“get”的结果会经过反序列化过程,它需要像上面这样的格式。

    您可以通过在 RedisTemplate 上使用不同的值序列化程序来解决此问题:

    redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
    

    或者试试 spring-data-redis 自带的 RedisAtomicLong 类。

    【讨论】:

      【解决方案2】:

      有点令人沮丧 - 感谢 RedisAtomicLong 的提示。但这里是使用带有字符串键、字符串字段和长值的 HashOps 的解决方案 - 使用 Spring Boot 来简化配置

      @SpringBootApplication
      @Configuration
      public class DemoApplication {
      
          public static void main(String[] args) {
              final ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
              final DacRepository dacRepository  = context.getBean(DacRepository.class);
              dacRepository.incrKeyExample();
          }
      
      
          @Bean
          public RedisTemplate<String, Long> getLongRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
               final RedisTemplate<String,Long> redisTemplate = new RedisTemplate<String, Long>();
               redisTemplate.setConnectionFactory(redisConnectionFactory);
               redisTemplate.setHashValueSerializer(new GenericToStringSerializer<Long>(Long.class));
               redisTemplate.setKeySerializer(new StringRedisSerializer());
               redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
               redisTemplate.setHashKeySerializer(new StringRedisSerializer());
               redisTemplate.afterPropertiesSet();
               return redisTemplate;
          }
      }
      
      import java.util.Set;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.data.redis.core.HashOperations;
      import org.springframework.data.redis.core.RedisTemplate;
      import org.springframework.stereotype.Repository;
      
      @Repository
      
      public class DacRepository {
      
          private final HashOperations<String, String, Long> hashOps;
      
          @Autowired
          private final RedisTemplate<String, Long> redisTemplate;
      
          @Autowired
          public DacRepository(RedisTemplate<String, Long> redisTemplate) {
              this.redisTemplate = redisTemplate;
              hashOps = redisTemplate.opsForHash();
      
          }
      
      
          public void incrKeyExample() {
              final Set<String> keys = this.redisTemplate.keys("*");
              for(String key: keys) {
                  System.out.println("key: "+ key);
              }
      
              final String key = "deal-1";
              final String field = "view";
              final Long value = 1L;
              hashOps.put(key, field, value);
              final Long delta = 1L;
              hashOps.increment(key, field, delta);
              Long val = hashOps.get("deal-1", "view");
              System.out.println("Value = "+val);
          }
      
      }
      
      
      
      
      server.port=9001
      spring.redis.host=localhost
      spring.redis.port=6379
      spring.redis.pool.max-idle=8
      spring.redis.pool.min-idle=0
      spring.redis.pool.max-active=8
      spring.redis.pool.max-wait=-1
      

      【讨论】:

        猜你喜欢
        • 2018-01-23
        • 1970-01-01
        • 2018-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-22
        • 2021-09-13
        • 2014-08-06
        相关资源
        最近更新 更多