需求是限制IP频繁访问某接口,用的方案是使用redis记录访问IP的值,先设定好初始值,每次访问自增,达到某限定值后,进行阻止。

用的是自定义工具类,使用spring封装的spring-data-redis进行操作,在对某key进行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;

}

第一次进来,如果没有redis中没有数据,则设置key,value和time,key是ip, value初始值为1,有效时长为10秒。

如果没达到限制次数,则对key自增1。

redisUtil.incr()方法实现如下:

@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方法接受的参数是long型,但我传入的是INTEGER类型,但转换后还是没有解决问题,问题不是出在这,后来通过查找资料发现,Spring对Redis序列化的策略有两种,分别是StringRedisTemplate和RedisTemplate,其中StringRedisTemplate用于操作字符串,RedisTemplate使用的是JDK默认的二进制序列化。

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

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

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

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); //注意这里是字节数组

}

}

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

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory factory) {

StringRedisTemplate template = new StringRedisTemplate(factory);

//定义key序列化方式

//RedisSerializer 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;

费了2多小时才成功解决问题,RedisUtil.incr()能够成功对key进行自增了,如有错误之处请欢迎指出。

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

  1. Spring Boot整合Redis以及Redis的原理

    Redis的原理及知识 Redis简介 redis是一个key-value.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  2. Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅)

    Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅) 1. 配置环境 在SpringBoot2.0版本以后,原来使用的jedis被替换成为了let ...

  3. spring boot shiro redis整合基于角色和权限的安全管理-Java编程

    一.概述 本博客主要讲解spring boot整合Apache的shiro框架,实现基于角色的安全访问控制或者基于权限的访问安全控制,其中还使用到分布式缓存redis进行用户认证信息的缓存,减少数据库 ...

  4. 大聪明教你学Java | Spring Boot 整合 Redis 实现访问量统计

    前言 之前开发系统的时候客户提到了一个需求:需要统计某些页面的访问量,记得当时还纠结了一阵子,不知道怎么去实现这个功能,后来还是在大佬的带领下借助 Redis 实现了这个功能.今天又回想起了这件事,正 ...

  5. Linux 安装Redis-6.2.5,配置及使用(RDB与AOF持久化、sentinel机制、主从复制、Spring Boot 集成 Redis)

    CentOS 7 安装Redis-6.2.5版本 Redis采用的是基于内存的单进程 单线程模型 的KV数据库,由C语言编写.官方提供的数据是可以达到100000+的qps 应用场景: 令牌(Toke ...

  6. Spring boot整合Redis(入门教程)

    目录 源码分析 jedis VS lettuce 整合测试 导入依赖 配置连接 测试 存入字符串 存入对象 五大数据类型操作 自定义RedisConfig 存入对象 Redis工具类(常用API) 以 ...

  7. 猿创征文 | 微服务 Spring Boot 整合Redis 实战开发解决高并发数据缓存

    文章目录 一.什么是 缓存? ⛅为什么用缓存? ⚡如何使用缓存 二.实现一个商家缓存 ⌛环境搭建 ♨️核心源码 ✅测试接口 三.采用 微服务 Spring Boot 注解开启缓存 ✂️@CacheEn ...

  8. Spring Boot与Redis的集成

    1.在Linux中安装Redis. 1.1.在线下载软件 1.2.安装软件 1.3.修改配置文件 1.4.启动Redis: 2.添加Redis起步缓存,在pom.xml中添加Spring Boot支持 ...

  9. 玩转spring boot——结合redis

    前言 Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了 ...

  10. 深入理解 Redis Template及4种序列化方式__spring boot整合redis实现RedisTemplate三分钟快速入门

    概述 使用Spring 提供的 Spring Data Redis 操作redis 必然要使用Spring提供的模板类 RedisTemplate, 今天我们好好的看看这个模板类 . RedisTem ...

最新文章

  1. Android性能优化常见问题,终局之战
  2. opencv python 图像去噪
  3. 累加出整个范围所有的数最少还需要几个数
  4. jieba是python中一个重要的标准函数库_python——Jieba库整理(基础知识+实例)
  5. 怎么来判断光端机产品的性能优劣?光端机的产品性能有哪些?
  6. 特征计算 - 遍历求值提速 6 万倍 lambda...if...else(if...else...) +map() 对比 iterrows() - Python代码
  7. 地表净辐射通量数据、太阳辐射量数据、降雨量数据、气温数据、日照时长、水汽压分布、风速风向数据、地表温度
  8. gson下载java_gson.jar
  9. 为什么说全球变暖不是阴谋论
  10. 【Html】 Html写静态淘宝页面
  11. uniapp uniCloud 云开发上传图片与查看图片
  12. 百钱百鸡问题最优解法
  13. i5 6600 HD530联想扬天S5250黑苹果
  14. eclipse中import existing projects into workspace和open projects from file systems分别有什么用?
  15. 按汉字首字母排序(sql语句) 只为收集,本人复制粘贴水寒冰局的
  16. DB2重启数据库实例
  17. FSF 公布 2022 年自由软件获奖名单
  18. ensemble learning 学习分享:回归问题
  19. 锂离子电池性能测试软件,锂电池性能测试检测方法有哪些
  20. 哈工大csapp lab3

热门文章

  1. HashMap,HashTable,ConcurrentHashMap面试总结!!!
  2. Linux之文档与目录结构
  3. 《memory leak: stackwalk》
  4. 安装php时,configure: error: xml2-config not found. Please check your libxml2 installation
  5. C++ 中的类型限定符 类型限定符提供了变量的额外信息。
  6. Microsoft Edge浏览器最新版已经换成开源Chromium引擎了,附官方下载地址
  7. 人脸识别领域相关金融标准将出台
  8. 从人工“智障”到人工智能,AI交互还缺什么?
  9. 机器学习中数据处理与可视化的python、numpy等常用函数
  10. 大学毕业后八大让你加班成狗专业盘点,你的专业上榜了嘛?