騰訊短信+SpringBoot+Redis實現註冊邏輯

 
使用redis作緩存實現用戶的註冊功能:
  •  異步請求發送短信,給 發送短信的按鈕 綁定異步事件
  • 調用發送短信邏輯發送短信
  • 緩存 key1:驗證碼
  • 緩存 key2:短信發送時刻的時間
  • 用戶提交表單 包含用戶的基本信息+驗證碼
  • 取出用戶的驗證碼去redis中查找
  • 若不存在返回異常
  • 未過時,直接退出發短信的方法
  •  存在根據key1取出驗證碼,和用戶提交的比對,相同繼續註冊,不然返回異常
主要調用騰訊短信的接口實現以下:
package com.sms.Utils;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import com.sms.properties.SmsRepository;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
 

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
 

/**
* 發送短信的工具類
* @Author: Changwu
* @Date: 2019/5/25 14:00
*/
@Component
@EnableConfigurationProperties(SmsRepository.class)
public class SendSms {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
SmsRepository smsRepository;
@Autowired
StringRedisTemplate stringRedisTemplate;
private String msg;
/**
* 發送短信
* 查看redis緩存中是否存在未過時的驗證碼信息,
* 若是存在直接返回,拒絕發送驗證碼,
* 不然從新發送
* @param photoNumber
* @return 發送的驗證碼
*/
public String sendSms(String photoNumber){
String key=smsRepository.getPREFIX()+photoNumber;
String lastTime = stringRedisTemplate.opsForValue().get(key);
// 判斷髮送的時長
if (lastTime!=null){
Long aLong = Long.valueOf(lastTime);
logger.info("lastTime==="+aLong);
if (System.currentTimeMillis()-aLong<smsRepository.getExpireTime()){
logger.warn("手機號{},發送短信頻率太高被拒絕..."+photoNumber);
return null;
}
}
// 生成隨機數
this.msg=createRodom();
// 發送短信
String errmsg = send(photoNumber,msg);
if (!errmsg.equals("OK")){
this.msg=errmsg;
throw new RuntimeException("故意整出來的異常");
}
// 把發送短信的時間寫入緩存
stringRedisTemplate.opsForValue().set(key,String.valueOf(System.currentTimeMillis()),smsRepository.getExpireTime()/1000, TimeUnit.SECONDS);
 

return msg;
}
 

/**
* 發送
* @param phone
* @param msg
*/
public String send(String phone,String msg){
SmsSingleSenderResult result =null;
try {
String time = String.valueOf(smsRepository.getExpireTime()/60000);
// 模板須要的兩個參數 , 驗證碼+過時時間
String[] params = {msg,time};
SmsSingleSender ssender = new SmsSingleSender(smsRepository.getAppid(), smsRepository.getAppkey());
// 單發短信
result = ssender.sendWithParam(
"86", // 國家碼,如 86 爲中國
phone, // 不帶國家碼的手機號
smsRepository.getTemplateId(), // 模板Id 指定信息內容
params, // 參數內容
smsRepository.getSmsSign(), // 簽名, 若是爲空,會使用默認的簽名
"", // 擴展碼,可填空
""); // 服務端原樣返回的參數,可填空
} catch (HTTPException e) {
// HTTP響應碼錯誤
e.printStackTrace();
} catch (JSONException e) {
// json解析錯誤
e.printStackTrace();
} catch (IOException e) {
// 網絡IO錯誤
e.printStackTrace();
}
// 保存驗證碼到redis
stringRedisTemplate.opsForValue().set(phone,msg,5,TimeUnit.SECONDS);
return result.errMsg;
}
 

// 建立六位隨機數
public String createRodom(){
Random random = new Random();
String result="";
for (int i=0;i<6;i++)
{
result+=random.nextInt(10);
}
return result;
}
}
 

```
 

配置類以下:
 

```java
/**
* @Author: Changwu
* @Date: 2019/5/25 15:39
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
@ConfigurationProperties(prefix = "sms")
public class SmsRepository {
 

// 短信應用SDK AppID // 1400開頭
private int appid ;
 

// 短信應用SDK AppKey
private String appkey ;
 

// 短信模板ID,須要在短信應用中申請
private int templateId ; // NOTE: 這裏的模板ID`7839`只是一個示例,真實的模板ID須要在短信控制檯中申請
 

// NOTE: 這裏的簽名"騰訊雲"只是一個示例,真實的簽名須要在短信控制檯中申請,另外簽名參數使用的是`簽名內容`,而不是`簽名ID`
private String smsSign;
 

// 緩存的前綴
private String PREFIX;
 

// 過時時間
private int expireTime;
 

}
 

  

配置文件

 

server:
port: 9999
spring:
redis:
host: 192.168.43.150
 

# 短信配置
sms:
appid: XXX #短信應用SDK AppID
appkey: XXX #短信應用SDK AppKey
templateId: 329108 # 短信模板ID,須要在短信應用中申請
smsSign: LFJHelper # 簽名--自定義
expireTime: 60000 # 過時時間,默認六十秒
PREFIX: PHOTO_SMS # 緩存進redis的key
相關文章
相關標籤/搜索