日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

java redis自增操作_【转载】关于spring boot使用redis的increment()方法自增问题

發(fā)布時間:2025/4/16 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java redis自增操作_【转载】关于spring boot使用redis的increment()方法自增问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

需求是限制IP頻繁訪問某接口,用的方案是使用redis記錄訪問IP的值,先設(shè)定好初始值,每次訪問自增,達(dá)到某限定值后,進(jìn)行阻止。

用的是自定義工具類,使用spring封裝的spring-data-redis進(jìn)行操作,在對某key進(jìn)行increment()方法時,報錯:

redis ERR value is not an integer or out of range

代碼邏輯如下:

Integer count = (Integer) redisUtil.get(ipAddress);//取得key的value

if (count == null){

redisUtil.set(ipAddress,1,10);

return false;

}else if(count == 3){

return false;

}else {

redisUtil.incr(ipAddress,1);

return false;

}

第一次進(jìn)來,如果沒有redis中沒有數(shù)據(jù),則設(shè)置key,value和time,key是ip, value初始值為1,有效時長為10秒。

如果沒達(dá)到限制次數(shù),則對key自增1。

redisUtil.incr()方法實現(xiàn)如下:

@Resource

private RedisTemplate redisTemplate; //這里使用的是redisTemplate

public void setRedisTemplate(RedisTemplate redisTemplate) {

this.redisTemplate = redisTemplate;

}

/**

* 遞增

* @param key 鍵

// * @param by 要增加幾(大于0)

* @return

*/

public long incr(String key, long delta){

if(delta<0){

throw new RuntimeException("遞增因子必須大于0");

}

return redisTemplate.opsForValue().increment(key, delta);

}

開始以為是incr方法接受的參數(shù)是long型,但我傳入的是INTEGER類型,但轉(zhuǎn)換后還是沒有解決問題,問題不是出在這,后來通過查找資料發(fā)現(xiàn),Spring對Redis序列化的策略有兩種,分別是StringRedisTemplate和RedisTemplate,其中StringRedisTemplate用于操作字符串,RedisTemplate使用的是JDK默認(rèn)的二進(jìn)制序列化。

大家都知道redis序列化是將key,value值先轉(zhuǎn)換為流的形式,再存儲到redis中。

RedisTemplate是使用的JdkSerializationRedisSerializer序列化,序列化后的值包含了對象信息,版本號,類信息等,是一串字符串,所以無法進(jìn)行數(shù)值自增操作。

而StringRedisTemplate序列化策略是字符串的值直接轉(zhuǎn)為字節(jié)數(shù)組,所以存儲到redis中是數(shù)值,所以可以進(jìn)行自增操作。

StringRedisSerializer源碼:

public class StringRedisSerializer implements RedisSerializer {

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); //注意這里是字節(jié)數(shù)組

}

}

所以問題出在這里,我們需要自定義序列化策略,在application啟動類中添加如下:

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory factory) {

StringRedisTemplate template = new StringRedisTemplate(factory);

//定義key序列化方式

//RedisSerializer redisSerializer = new StringRedisSerializer();//Long類型會出現(xiàn)異常信息;需要我們上面的自定義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;

費(fèi)了2多小時才成功解決問題,RedisUtil.incr()能夠成功對key進(jìn)行自增了,如有錯誤之處請歡迎指出。

總結(jié)

以上是生活随笔為你收集整理的java redis自增操作_【转载】关于spring boot使用redis的increment()方法自增问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。