当我调用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方法时,没有例外但只有错误才会获得方法
这是堆栈跟踪---
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)
答案 0 :(得分:8)
默认情况下,RedisTemplate使用JdkSerializationRedisSerializer,因此如果您执行了&#34; set&#34;它会让你的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不会尝试反序列化结果。然而,&#34; get&#34;的结果经历了反序列化过程,该过程需要类似上述的格式。
您可以在RedisTemplate上使用不同的值序列化程序来解决此问题:
redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
或者尝试使用spring-data-redis附带的RedisAtomicLong类。
答案 1 :(得分:6)
有点令人沮丧 - 感谢RedisAtomicLong上的提示......但这里有一个使用HashOps与String Key,String字段和Long值的解决方案 - 使用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