阿里云短信服务地址:https://api.aliyun.com/new?spm=a2c4g.11186623.2.13.c17919d92bTijk#/?product=Dysmsapi&api=SendSms&tab=DEMO&lang=JAVA
accessKeyId:需申请获取
accessSecret:需申请获取
SignName:需自行设置
TemplateCode:需自行设置
需要引入阿里云的maven
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.3</version>
</dependency>
找回密码请求,获取手机号 发送验证码
SendSms.Send(user.getPhonenum());
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Created by on 2019/11/8.
* 阿里云短信验证码api
* 工具类
* 更换必要参数直接使用
*/
@Component
public class SendSms {
private static String accessKeyId ;
private static String accessKeySecret ;
private static String SignName ;
private static String TemplateCode ;
//读取配置
public static String getAccessKeyId() {
return accessKeyId;
}
@Value("${accessKeyId}")
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public static String getAccessKeySecret() {
return accessKeySecret;
}
@Value("${.accessKeySecret}")
public void setAccessKeySecret(String accessKeySecret) {
SendSms.accessKeySecret = accessKeySecret;
}
public static String getSignName() {
return SignName;
}
@Value("${SignName}")
public void setSignName(String signName) {
SignName = signName;
}
public static String getTemplateCode() {
return TemplateCode;
}
@Value("${TemplateCode}")
public void setTemplateCode(String templateCode) {
TemplateCode = templateCode;
}
//传入手机号
public static void Send(String phonenum) {
//随机生成4位随机数
StringBuffer stringBuffer=new StringBuffer();
for (int x=0;x<=3;x++) {
int random = (int) (Math.random() * (10 - 1));
stringBuffer.append(random);
}
String string = stringBuffer.toString();
int i = Integer.parseInt(string);
//设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化ascClient,暂时不支持多region(请勿修改)
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
IAcsClient client = new DefaultAcsClient(profile);
//组装请求对象
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("RegionId", "cn-hangzhou");
//必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
request.putQueryParameter("PhoneNumbers",phonenum);
//必填:短信签名-可在短信控制台中找到
request.putQueryParameter("SignName", SignName);
//必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
request.putQueryParameter("TemplateCode", TemplateCode);
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.putQueryParameter("TemplateParam", "{\"code\":"+i+"}");
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
// request.putQueryParameter("SmsUpExtendCode", "tyhrt");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
// request.putQueryParameter("OutId", "45345");
//请求失败这里会抛ClientException异常
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println("sms-api返回值:"+response.getData());
if(response.getHttpStatus()==200) {
String data = response.getData();
JSONObject jsonObject = (JSONObject)JSONObject.parse(data);
String code = jsonObject.getString("Code");
if ("OK".equals(code)){
CacheHashMap.putData(phonenum,i+"");
}
System.out.println("短信验证码=="+i);
}
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
}
缓存验证码
public class CacheHashMap {
// 设置过期时间
private static final Long timeout = 5 * 1000 * 60L;
// 创建一个Map用来保存数据
private static Map<String, List> cache = new HashMap<>();
// 设置list中的索引 0 表示数据索引
private static final Integer DATA_INDEX = 0;
// 设置list中的索引 1 表示保存的时间戳索引
private static final Integer TIME_INDEX = 1;
// 创建一个静态的Map用来保存
private static CacheHashMap cacheHashMap;
// 构造方法私有化不能创建对象
private CacheHashMap() {
}
/**
* 用来清理一些,用户没有用过的验证码。可以半小时来清理一次。
*/
public static void clearData() {
for (String key : cache.keySet()) {
List list = cache.get(key);
Long settime = (Long) list.get(TIME_INDEX);
// 获取当前时间戳
long nowtime = System.currentTimeMillis();
if (nowtime - settime > timeout) {
cache.remove(key);
}
}
}
/**
* @param code 验证码
* @param key 储存数据的key
* @return
*/
// 储存数据
public static void putData(String key, String code) {
List list = new ArrayList();
list.add(code);
list.add(System.currentTimeMillis());
cache.put(key, list);
}
/**
* @param key 取出数据的key
* @return 返回数据值 null为不存在。
*/
// 取出数据
public static String getData(String key) {
List list = cache.get(key);
Object o = list.get(DATA_INDEX);
Long settime = (Long) list.get(TIME_INDEX);
// 获取当前时间戳
long nowtime = System.currentTimeMillis();
if (nowtime - settime > timeout) {
cache.remove(key);
return null;
}
cache.remove(key);
return (String) o;
}
}
logger.info("检测验证码");
User user = userService.findByUsername(username);
String data = CacheHashMap.getData(user.getPhonenum());
if ( data.equals(code)){
flag = true;
}