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