今天是个周六,还在苦逼加班的我对那些休周末的同行表达羡慕嫉妒,对那么同样加班的同行共勉吧~~
整理了下这周的工作进度。除了项目试上线以外也就是补充补充之前遗留下的小问题了。这篇文章就是说手机号每天接受验证码的条数限制。
我们现在的好多程序注册需要手机号并且发送验证码来验证手机号的真伪。以前常用的就是阿里的发送短信的功能(感觉这个真的很常用,阿里的产品还是值得信赖的)。不过我们这个项目采用的是极光的短信功能。不过这个其实不重要,因为我们来限制一个手机号 一天可以发多少短信和短信平台无关。我这里是因为老板说听说某某程序员说受到过这样的攻击,不到一个小时一个产品发出去几千块钱的短信费用。而且我另一个朋友也说过如果不加以限制可能他一个多线程跑过去我们平台的短信费用立刻欠费。
这里说一下具体的思路:因为确实有时候我们在注册的时候会发送各种意外。比如当时信号不好啊,或者莫名其妙的手机短信没收到啊不可避免的,所以一个人一天只能发一条短信肯定也不合理。然后我们老板目前设置的是一个人一天能接收的验证码是10条(多了少了是可以设置的。不过我接下的例子也是一个手机号码一天可以接收十条验证码)。我这里采用的是存redis来实现这一个功能的(感觉这里数据库也可以实现,但是不如reids好。最近敲喜欢redis的说,用起来得心应手,哈哈)。就是每次调用发送验证码这个接口都会判断手机号码是否在redis中存为key了。如果没有则创建一个key为手机号码value是1.因为redis中不支持数字所以我是1+“”将其变为了string类型。如果redis中已经有这个key了则将此key的值取出来加1再存进redis中。这里在做的时候过期问题有一点小纠结。最后想明白了。我们老板的要求是每天。也就是这个key-value的存活期应该是到今天结束。所以我又专门做了个小工具类来获取当前时间到今天结束时间(也就是23点59分59秒999毫秒+1毫秒的时间)的毫秒数。并将此作为这个key的到期时间的(关于这个我是给予我的实际情况来设计的,如果亲们有啥别的具体的需求可以酌情更改)。
这里上一下代码:
首先是获取当前时间到今天结束时间所剩余的毫秒数:
/**
* 获取当前时间到今天结束 的毫秒数
*因为这个是工具类里面的方法所以是静态的
* @return
*/
public static long getEndTime() {
//获取当前时间的毫秒数
long time = new java.util.Date().getTime();
//获取到今天结束的毫秒数
Calendar todayEnd = Calendar.getInstance();
todayEnd.set(Calendar.HOUR_OF_DAY, 23); // Calendar.HOUR 12小时制。HOUR_OF_DAY 24小时制
todayEnd.set(Calendar.MINUTE, 59);
todayEnd.set(Calendar.SECOND, 59);
todayEnd.set(Calendar.MILLISECOND, 999);
long endTime = todayEnd.getTimeInMillis();
//这里endTime-time获取的是到23:59:59:999的毫秒数。再加1才是到24点整的毫秒数
return endTime-time+1;
}
然后发送短信接口的代码:
public ResultBean SendSMSCode(String tel) {
if("10".equals(stringRedisTemplate.opsForValue().get(tel))) {
return Tools.result(200, "您的手机号码已达到发送验证码次数上限", null, false);
}
SMSClient client = new SMSClient(masterSecret, appkey);
SMSPayload payload = SMSPayload.newBuilder().setMobileNumber(tel).setTempId(1).build();
try {
//这句代码是真正发送验证码的方法。如果你们用别的平台的接口也应该有一句话是真正发送的代码。
SendSMSResult res =client.sendSMSCode(payload);
if(stringRedisTemplate.opsForValue().get(tel)==null) {
stringRedisTemplate.opsForValue().set(tel, "1", Tools.getEndTime(), TimeUnit.MILLISECONDS);
}else {
String value = stringRedisTemplate.opsForValue().get(tel);
int times = Integer.parseInt(value)+1;
String timesStr = String.valueOf(times);
stringRedisTemplate.opsForValue().set(tel, timesStr, Tools.getEndTime(), TimeUnit.MILLISECONDS);
}
return Tools.result(200, "发送验证码成功", res, true);
} catch (Exception e) {
LOG.info("Error Message: " + e.getMessage());
return Tools.result(500, "发送验证码失败", null, false);
}
}
额,还是大概说一下代码的逻辑吧。首先进入到这个接口就要判断此手机号是否已经发到了10次上限。如果已经发到了则直接返回限制。如果没达到每日上限才往下继续。然后加粗的这几句都是发送短信的代码。平台不一样肯定不是一种写法。就不多说了。然后是等短信发送成功了才操作的。这一点很注意,短信发送成功才算一次次数。然后判断redis中是否有次手机号为key,如果没有则创建一个,值是1,如果有则在原来的基础上+1。没啥复杂的逻辑操作,就是一个思路而已。然后每次过期时间都是根据当前时间来获取的。单位是毫秒。如果业务需求是24小时什么的也可以灵活改动。
感觉代码中也没啥有难度的地方。如果说有看不懂的比如说对redis操作看不懂可以跳转专门讲StringRedisTemplate的文章:
然后有更好的实现方式或者思路的可以留言或者私聊我~~
全文手打~~这么不容易的写个文~~如果你觉得用到了~留个言点个赞转个发什么的啊~
本站以现代、古代情诗为主,情诗网创办于2013年,以原创爱情诗歌、经典情诗、现代情诗、古代情诗、英文情诗、情诗绝句为主并收集古诗、古诗词、诗歌大全、诗词名句的文学门户。方便您下次继续阅读;可以放在浏览器的收藏夹中(快捷键Ctrl+D);或者看到喜欢或者有趣的诗词可以通过分享按钮给你的好友分享;情诗网是目前最全情诗大全网站之一。并欢迎广大诗歌爱好者阅览投稿!喜欢本站的话请大家把本站告诉给你朋友哦!地址是 www.qingshiwang.com !