首先进入阿里云控制台,点击左侧产品与服务,找到短信服务。
第一次进入会有新手引导,这里主要介绍一下大致步骤和易错点
短信签名一般是企业或者组织名的简写,主要是告知收信人自己是谁。一般体现在短信的开头,用括号括住。
【Dresults】您的验证码:139267,您正进行身份验证,打死不告诉别人!
模板就是我要发送内容的模板,每条短信共有的部分,将变化的部分抽出作为变量,体现在代码中。注意,短信模板具有类型,且不同类型收费标准不同,这里就先介绍短信验证码
至于模板具体选择,可以自定义也可以使用常用模板库(完全免费的),切记模板要遵守一定的规范。
最后是申请说明,这里大家简要介绍一下此模板的应用场景或者介绍一下自己或公司,一般没什么用。提交申请后2小时左右就会收到审批通知
这步一般不需要什么操作,因为阿里云短信收费是预先缴费,按量付费。只要阿里云账号有钱就可以,不需要订购。
这步还是要仔细看一下,主要是安全设置,有防盗刷机制,这里不详细展开,阿里云的文档还是很详细的。
有两种方式,分别是API发送和群发助手进行短信群发。这里介绍API发送
查看开发者指南—不同编程语言的短信服务SDK(Software Development Kit 软件开发工具包)—JAVA SDK DEMO
按照图示箭头一次选择,这里取消只看必填参数,后面如果需要扩展再自行选择(必填参数中没有验证码参数)
这里的三个参数介绍一下,一开始是默认不填参数的,右侧的代码中也没有对于的参数,我们手动填写后,代码中才会出现参数。还有代码中的内容除了我们自己填写的,其他都不要修改,下面这个不是时间,是版本号,修改了就会出错,其他也一样。
request.setSysVersion("2017-05-25");
鼠标放到用户头像处,点击下拉选项AccessKey管理,进入页面后,创建AccessKey。输入手机验证码后,就创建成功了。注意****这是唯一一次保存键和密码的时间,保存到本地上,以后就不可查看了,只能删除重建。
AccessKey ID和AccessKey Secret相当于是阿里云账号的一个子账号,起到验证作用,可以用这个账号来调用阿里云API服务。
第一个参数,PhoneNumber手机号,第二个SignName签名名称(必须审核通过的才行);第三个TemplateCode短信模板ID(是模板管理的模板CODE);第四个是短信验证码模板变量参数(这里用json格式{“code”:“123456”},注意要用小写。验证码的值后面代码中用随机数替代,code按照自己模板中的写,一般是code)
最后可以尝试发起调用,这里测试不需要花钱。可以真实发送短信。
public class MessageUtil {
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi";
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com";
static final String accessKeyId = "填自己的";
static final String accessKeySecret = "填自己的";
@Autowired
private RedisRepository redisRepository;
public MessageDto getSsm(String number) {
if (number.equals("") || number == null) {
throw new SysException("没有填写手机号");
}
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
try {
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
} catch (ClientException e1) {
e1.printStackTrace();
}
IAcsClient acsClient = new DefaultAcsClient(profile);
//随机生成六位验证码
int code = (int) ((Math.random() * 9 + 1) * 100000);
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
//必填:待发送手机号
request.setPhoneNumbers(number);
//必填:短信签名-可在短信控制台中找到,你在签名管理里的内容
request.setSignName("填自己的");
//必填:短信模板-可在短信控制台中找到,你模板管理里的模板编号
request.setTemplateCode("填自己的");
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
request.setTemplateParam("{\"code\":\"" + code + "\"}");
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
//request.setOutId("yourOutId");
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = null;
try {
sendSmsResponse = acsClient.getAcsResponse(request);
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
//获取发送状态
MessageDto messageDto = new MessageDto(code, sendSmsResponse.getCode());
//保存手机验证码至redis中,大家没有用的话可以保存在mysql数据库中
redisRepository.saveMessageCode(number, String.valueOf(code));
log.info(number + ": 发送了一条验证码");
return messageDto;
}
}
这里介绍我对验证码的理解,验证码一般是用在登录或注册处的,为的就是防止机器暴力调用接口,造成资源的浪费。
具体流程是,先按下发送验证码的按钮,这时手机会收到短信。下一步就是我们最初的目的,或是登录或是注册,选项中有一项为输入验证码。输入后,后台会校验手机号和验证码是否对应。所以在发送验证码后,后台要将手机号和验证码的键值对保存起来。保存的地方可以是mysql,也可以是redis。
如果是redis,本身就具备了键值对的对应关系,只需要保存就好。
如果是Mysql,需要我们建表,并加上两列,分别是手机号和验证码。
这里介绍一下redis的代码部分
RedisUtil为工具类,直接接触redis
public class RedisUtil {
public static boolean exists(StringRedisTemplate redisTemplate, String key) {
return redisTemplate.hasKey(key);
}
public static<T> void set (StringRedisTemplate redisTemplate, String key, T value) {
redisTemplate.opsForValue().set(key, JsonUtil.toJson(value));
}
public static<T> T get (StringRedisTemplate redisTemplate, String key, Class<T> clazz) {
String value = redisTemplate.opsForValue().get(key);
if (null != value) {
return JsonUtil.toObject(value, clazz);
}
return null;
}
public static void del(StringRedisTemplate redisTemplate, String key) {
redisTemplate.delete(key);
}
}
这个RedisRepository的实现类
里面有一处代码需要注意,RedisKeyTemplate.T_VERIFICATION_CODE,这个在最后的代码块中能发现,是给redis空间命名。相信聪明的大家肯定可以明白的。
RedisUtil.set(redisTemplate, RedisKeyUtil.buildKey(RedisKeyTemplate.T_VERIFICATION_CODE, phone), messageCode);
@Component
public class RedisRepositoryImpl implements RedisRepository {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 保存手机号和验证码的键值对
*
* @param phone
* @param messageCode 验证码
*/
@Override
public void saveMessageCode(String phone, String messageCode) {
RedisUtil.set(redisTemplate, RedisKeyUtil.buildKey(RedisKeyTemplate.T_VERIFICATION_CODE, phone), messageCode);
}
@Override
public String selectMessageCodeByPhone(String phone) {
return RedisUtil.<String>get(redisTemplate, RedisKeyUtil.buildKey(RedisKeyTemplate.T_VERIFICATION_CODE, phone), String.class);
}
}
public interface RedisRepository {
/**
* 保存手机号和验证码的键值对
* @param phone
* @param messageCode 验证码
*/
void saveMessageCode(String phone, String messageCode);
/**
* 根据key:手机号 查询验证码
* @param phone
* @return
*/
String selectMessageCodeByPhone(String phone);
}
public class RedisKeyTemplate {
/**
*记录验证码信息
* 键:Verification_Code:verificationCode
* 值:{ verificationCode, phoneNumber }
*/
public final static String T_VERIFICATION_CODE = "Verification:%s";
}