判断一个小时之内是否重复发送了10次短信
并且是同一个手机
每次发送短信,要写入当前时间戳到redis:
- String mobile="13718486139";
- String time=String.valueOf(DateTimeUtil.getCurrentMillisecond());
- RedisHelper.getInstance().saveKeyCache("limit_one_hour", mobile+"_"+time, time);
检查时先获取所有时间戳:
- Map map=RedisHelper.getInstance().getAllKeyCache("limit_one_hour");
具体判断逻辑:
- @Test
- public void test_limitOneHour2(){
- String mobile="13718486139";
- int limitCount=5;
- int limitTime=2*60;//两分钟
- Map<String,String> map=new HashMap<String,String>();
- map.put("13718486139_1445429819328", "1445431479437");
- map.put("13718486139_1445429874699", "1445431485996");
- map.put("13718486139_1445429874799", "1445431491527");
- map.put("13718486139_1445430757886", "1445431496853");
- System.out.println(map);
- List<Long>list=new ArrayList<Long>();
- for(String key:map.keySet()){
- if(key.startsWith(mobile)){
- list.add(Long.parseLong(map.get(key))/1000);
- }
- }
- SortList<Long>sortUtil=new SortList<Long>();
- sortUtil.Sort(list, "longValue", "desc");
- int length=list.size();
- int toIndex=0;//要截取的最大序号
- if(limitCount>length){
- toIndex=length;
- }else{
- toIndex=limitCount;
- }
- List<Long>result=list.subList(0, toIndex);
- long delter=list.get(0).longValue()-list.get(toIndex-1).longValue();
- long delterSecond=delter;
- System.out.println(delterSecond);
- if(delterSecond<limitTime){
- System.out.println("超限");
- }else{
- System.out.println("可以继续发短信");
- }
- System.out.println(result);
- }
步骤:
(1)把当前手机号的所有时间戳放入list中;
(2)对list排序,按时间顺序,从大到小;(时间越大,表示离现在越近)
(3)根据次数(limitCount)限制 来截取list;
(4)计算list中第一个元素和最后一个元素的差量,即limitCount条短信的时间跨度delter
(5)若delter 小于时间限制limitTime,则表示超过限制,那么禁止发送短信
问题
为什么要以这种方式存储到redis?
"limit_one_hour" "13718486139_1445429819328" "1445431496853"
而不是直接以手机号为key
13718486139 "1445431496853" ""
因为:可能其他redis项是以手机号为key的,这样就会覆盖掉.即这样做有风险.
不过如下方式可以:
13718486139_limit_one_hour "1445431496853" ""