阿里云短信平台,能够提供三种短信模板形式(一、验证码模板;二、通知类消息模板;三、推广短信模板)html
验证码模板形式:验证码${code},您正在进行身份验证,打死不要告诉别人哦!java
通知类消息模板:尊敬的${name}用户,恭喜您成功注册为本商城的会员用户,相信本商城会为您带来良好的体验效果,祝您生活愉快!数据库
推广短信模板:短信测试,短信测试,短信测试,短信测试,短信测试,短信测试api
(注:推广短信模板无需参数,其余两个均须要)缓存
(注意:如下方法基本放在service层)dom
一、下载SDK工具包异步
SDK工具包中一共包含了2个类库,一个aliyun-java-sdk-core包,另一个是alicom-dysms-api包,将这两个包执行mvn package命令或者mvn deploy命令打包出相应的jar包,添加到工程类库中依赖使用。async
SDK&DEMO[下载地址]ide
一、编写短信统一处理函数函数
SendSmsResponse send(String mobiles, String content, String TemplateCode);
返回值:SendSmsResponse (用于肯定是否发送短信成功),判断条件:
if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) { System.out.print("success"); }
参数:mobiles须要发送的电话号码,如果多个,用 "," 隔开,形式:"13472266942,17600693094"
content是模板中的变量及变量值,若变量为name,code,则content形式{"name":"Tom", "code":"SUMY"},
当不发送推广短信的时候,须要逐条发送,由于每条短信内容的变量值不一样,只有推广短信能够批量发送
TemplateCode是阿里云短信模板中的模板CODE,用于接口判断模板内容,至关于数据库中的id
/** * @desc: 阿里短信发送 * @return: SendSmsResponse * @author: gxl * @datetime 2017年12月1日, 下午9:32:12 */ private SendSmsResponse send(String mobiles, String content, String TemplateCode) throws ClientException, InterruptedException {
//mobiles为要发送的电话号码,content模板变量的替换,TemplateCode为模板CODE(能够在阿里云平台上找到) SendSmsResponse sendSmsResponse; //可自助调整超时时间 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 = "accessKeyId"; final String accessKeySecret = "accessKeySecret "; //初始化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个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000” request.setPhoneNumbers(mobiles); //必填:短信签名-可在短信控制台中找到-填写本身的短信签名 request.setSignName("Tom"); //必填:短信模板-可在短信控制台中找到 request.setTemplateCode(TemplateCode); //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为{"name":"Tom", "code":"SMKU"} //友情提示:若是JSON中须要带换行符,请参照标准的JSON协议对换行符的要求,好比短信内容中包含\r\n的状况在JSON中须要表示成\\r\\n,不然会致使JSON在服务端解析失败
//若是短信为推广短信,则无需使用request.setTemplateParam(content); if (!content.equals("")) { request.setTemplateParam(content); } //可选-上行短信扩展码(扩展码字段控制在7位或如下,无特殊需求用户请忽略此字段) //request.setSmsUpExtendCode("90997"); //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者 //request.setOutId("yourOutId"); // 请求失败这里会抛ClientException异常 sendSmsResponse = acsClient.getAcsResponse(request); //判断是否发送成功 if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) { System.out.print("success"); } return sendSmsResponse; }
二、发送验证码(须要调用上面的方法)
/** * @desc: 发送验证码 * @return: SendSmsResponse * @author: gxl * @datetime 2017年12月1日, 下午9:33:52 */ @Override public SendSmsResponse sendCaptcha(String mobeiles, Long id) { //获取一个验证码 String captcha = captchaProducer.createText();
//将验证码和模板变量组合成content String content = "{\"code\":\"" + captcha + "\"}"; try {
//调用上面所写的函数,注意“SMS_130820049”是本身申请的模板CODE SendSmsResponse send = send(string, content, "SMS_130820049");
//将验证码加入缓存,send.getBizId()为缓存中的key值,captcha为缓存中的value值,目的是为了后面对验证码进行校验 Ehcache cache = cacheManager.getEhcache("smsCaptcha"); cache.put(new Element(send.getBizId(), captcha)); return send; } catch (ClientException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return null; }
短信验证:
public boolean isValid(String smsCaptchaId, String smsCaptcha) { if (StringUtils.isEmpty(smsCaptchaId) || StringUtils.isEmpty(smsCaptcha)) { return false; } Ehcache cache = cacheManager.getEhcache(SMS_CAPTCHA_CACHE_NAME); Element element = cache.get(smsCaptchaId); if (element != null) { String value = (String) element.getObjectValue(); Boolean flag = StringUtils.equalsIgnoreCase(smsCaptcha, value); if(flag){ cache.remove(smsCaptchaId); } return flag; } return false; }
三、发送通知类短信或推广短信
此处使用List<String> mobileList 目的是为了方便推广短信编写手机号码,使其批量发送,最多每次只能够发送1000条,固然发送通知类短信的时候,List里面只有一条电话号码,注意在调用的时候不要写错
同步发送的时候,须要等待发送完短信再进行下一步操做;异步发送短信,不须要等待将短信发送完就能够进行下一步操做
/** * 发送短信 * * @param mobiles * 手机号码 * @param content * 内容 * @param templateCode * 模板 * @param async * 是否异步 */ public void send(List<String> mobileList, String content, String templateCode, boolean async) { Assert.notEmpty(mobileList); //每次批量发送最多1000条 for (int j = 0;; j += 1000) { Integer k = j; String mobiles = ""; for(Integer i=j; i<j+1000 && i<mobileList.size();i++, k++){ mobiles = mobiles + mobileList.get(i) + ","; } //判断同步发送短信,仍是异步 if (async) { //注意更改 addSendTask(mobiles, content, templateCode); } else { try {
//调用1中的方法,发送短信 send(mobiles, content, templateCode); } catch (ClientException | InterruptedException e) { e.printStackTrace(); } } if (k >= mobileList.size()) { break; } } }
异步发送短信(即,新建一个进程)
/** * 添加短信发送任务 * * @param mobiles 手机号码 * @param content 内容 * @param templateCode 模板CODE */ private void addSendTask(final String mobiles, final String content,final String templateCode) { taskExecutor.execute(new Runnable() { @Override public void run() { try {
//发送短信 send(mobiles, content, templateCode); } catch (ClientException | InterruptedException e) { e.printStackTrace(); } } }); }
(注意:若是无需同步、异步,根据自身的需求更改代码)