分类
Java 编程

Spring Data 使用 Redis 自增方法报错

Spring Data Redis 的 RedisTemplate 对 Redis 进行了封装。在对某值调用increment()方法时报错:

redis ERR value is not an integer or out of range

redisTemplate.opsForValue().increment(key);

大家都知道redis序列化是将key,value值先转换为流的形式,再存储到redis中。

RedisTemplate是使用的JdkSerializationRedisSerializer序列化,序列化后的值包含了对象信息,版本号,类信息等,是一串字符串,所以无法进行数值自增操作。

而StringRedisTemplate序列化策略是字符串的值直接转为字节数组,所以存储到redis中是数值,所以可以进行自增操作。

StringRedisSerializer源码:

public class StringRedisSerializer implements RedisSerializer<String> {
    private final Charset charset;

    public StringRedisSerializer() {
        this(StandardCharsets.UTF_8);
    }

    public StringRedisSerializer(Charset charset) {
        Assert.notNull(charset, "Charset must not be null!");
        this.charset = charset;
    }

    public String deserialize(@Nullable byte[] bytes) {
        return bytes == null ? null : new String(bytes, this.charset);
    }

    public byte[] serialize(@Nullable String string) {
        return string == null ? null : string.getBytes(this.charset); //注意这里是字节数组
    }
}

所以问题出在这里,我们需要自定义序列化策略,在application启动类中添加如下:

@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
	StringRedisTemplate template = new StringRedisTemplate(factory);
	//定义key序列化方式
	//RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
	//定义value的序列化方式
	Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
	ObjectMapper om = new ObjectMapper();
	om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
	om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
	jackson2JsonRedisSerializer.setObjectMapper(om);

	// template.setKeySerializer(redisSerializer);
	template.setValueSerializer(jackson2JsonRedisSerializer);
	template.setHashValueSerializer(jackson2JsonRedisSerializer);
	template.afterPropertiesSet();
	return template;
}

原文:https://www.cnblogs.com/qsymg/p/9830877.html

发表评论

电子邮件地址不会被公开。