SpringBoot2.0(三):SpringBoot2.0配置阿里云短信和Redis
https://blog.csdn.net/xiaofeivip_top/article/details/88408923
二、下载安装Redis
https://blog.csdn.net/xiaofeivip_top/article/details/88379561
三、application.properties添加redis配置
四、导入阿里云的jar
<!-- 阿里云短信 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.6</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
五、Service层
/**
* Redis 服务层
* @author xiaofei
*/
public interface IMyRedis {
/**
* 设置key-value
* @param key
* @param value
*/
void set(String key, String value);
/**
* 设置key-value-timeout
* @param key
* @param value
* @param timeout
*/
void set(String key, String value, int timeout);
/**
* 根据key获取值
* @param key
* @return
*/
String get(String key);
/**
* 根据key删除值
* @param key
*/
void del(String key);
Long incr(String key);
Long decr(String key);
void setExp(String key, int seconds);
Long getExp(String key);
void lpush(String key, Object value);
Object rpop(String key);
void hset(String key, String item, String value);
String hget(String key, String item);
void hdel(String key, String item);
/**
* 发送验证码
* @param phone 手机号
* @param random 验证码长度
* @param alyAccessKeyId
* @param alyAccessKeySecret
* @param redis redis
* @param invalid 失效时间(单位秒)
* @return 成功(返回数字) error 失败
* @throws ClientException
*/
String sendSms(String phone,Integer random,String alyAccessKeyId,String alyAccessKeySecret,IMyRedis redis,Integer invalid) throws Exception;
/**
* 验证手机号和验证码
* @param phone 手机号
* @param code 验证码
* @param redis redis
* @param num 错误次数
* @return
*/
String checkSms(String phone,String code,IMyRedis redis,Integer num);
}
六、ServiceImpl
/**
* @author xiaofei
*/
@Service
public class MyRedisImpl implements IMyRedis {
@Autowired
private StringRedisTemplate template;
@Override
public void set(String key, String value) {
ValueOperations<String,String> operations = template.opsForValue();
operations.set(key,value);
}
@Override
public void set(String key, String value, int timeout) {
ValueOperations<String, String> operations = template.opsForValue();
operations.set(key,value,timeout, TimeUnit.SECONDS);
}
@Override
public String get(String key) {
ValueOperations<String, String> operations = template.opsForValue();
return operations.get(key);
}
@Override
public void del(String key) {
template.delete(key);
}
@Override
public Long incr(String key) {
ValueOperations<String, String> operations = template.opsForValue();
Long increment = operations.increment(key,1);
return increment;
}
@Override
public Long decr(String key) {
ValueOperations<String, String> operations = template.opsForValue();
Long increment = operations.increment(key,-1);
return increment;
}
@Override
public void setExp(String key, int seconds) {
template.expire(key,seconds,TimeUnit.SECONDS);
}
@Override
public Long getExp(String key) {
Long expire = template.getExpire(key);
return expire;
}
@Override
public void lpush(String key, Object value) {
ListOperations list = template.opsForList();
list.leftPush(key,value);
}
@Override
public Object rpop(String key) {
ListOperations opsForList = template.opsForList();
return opsForList.rightPop(key);
}
@Override
public void hset(String key, String item, String value) {
HashOperations<String, Object, Object> opsForHash = template.opsForHash();
opsForHash.put(key,item,value);
}
@Override
public String hget(String key, String item) {
HashOperations opsForHash = template.opsForHash();
return (String) opsForHash.get(key,item);
}
@Override
public void hdel(String key, String item) {
HashOperations opsForHash = template.opsForHash();
opsForHash.delete(key,item);
}
@Override
public String sendSms(String phone, Integer random, String alyAccessKeyId, String alyAccessKeySecret, IMyRedis redis, Integer invalid) throws Exception {
//设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化ascClient需要的几个参数
final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
//替换成你的AK
final String accessKeyId = alyAccessKeyId;//你的accessKeyId,参考本文档步骤2
final String accessKeySecret = alyAccessKeySecret;//你的accessKeySecret,参考本文档步骤2
//初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
SendSmsRequest request = new SendSmsRequest();
//使用post提交
request.setMethod(MethodType.POST);
//必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为国际区号+号码,如“85200000000”
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName("饶付");
//必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
request.setTemplateCode("SMS_123671650");
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
//生成6位的动态验证码
String numeric = StringUtils.getRandom(random);
request.setTemplateParam("{\"code\":\"" + numeric + "\"}");
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
redis.set("sms_" + phone, numeric, invalid);
return numeric;
} else {
return "String";
}
}
@Override
public String checkSms(String phone, String code, IMyRedis redis, Integer num) {
//获取redis中存放的验证码
String redisCode = redis.get("sms_" + phone);
if (code != null && !"".equals(code)) {
//如果用户输入的验证码和生成的验证码保持一致
if (code.equals(redisCode)) {
//删除redis中存放的验证码缓存
redis.del("sms_" + phone);
//同时删除redis中存放的用户输入验证码的错误次数
redis.del("error_" + phone);
return "OK";
} else {
//如果验证失败 给该用户总共三次输入机会,大于三次重新获取验证码
//如果是第一次错误,则第一次给用户创建错误次数并存放于redis中,每次错误都会在原有的键上对其值+1
Long incr = redis.incr("error_" + phone);
if (incr > num) { //如果用户错误的次数大于三次
//清除旧的验证码
redis.del("sms_" + phone);
//清除redis中存放的用户输入验证码的错误次数
redis.del("error_" + phone);
return "超过验证码错误次数,请重新获取验证码!";
}
}
}
return "验证码不能为空!";
}
七、验证码生成类
/**
* 生成指定位数的验证码
* @param value
* @return
*/
public static String getRandom(Integer value) {
String sum = "";
for (int i = 0; i < value; i++) {
sum += String.valueOf((int) Math.floor(Math.random() * 9 + 1));
}
return sum;
}
八、测试
/**
* 短信验证码发送测试
* @return
*/
@RequestMapping(value = "/sms")
@ResponseBody
public String testSms() {
String msg = null;
try {
msg = iMyRedis.sendSms("手机号",6,accessKeyId,accessKeySecret,iMyRedis,30);
}catch (Exception e) {
// e.printStackTrace();
System.err.println("error");
}
return msg;
}
/**
* 短信验证码 验证
* @return
*/
@RequestMapping(value = "/checkSms")
@ResponseBody
public String checkSms(String code) {
String msg = null;
try {
msg = iMyRedis.checkSms("手机号",code,iMyRedis,3);
}catch (Exception e) {
System.err.println("error");
}
return msg;
}
免费发短信接口:
https://blog.csdn.net/xiaofeivip_top/article/details/88408923