阿里云短信发送

时间:2021-05-17 18:33:23

    阿里云短信平台,可以提供三种短信模板形式(1、验证码模板;2、通知类消息模板;3、推广短信模板)

    验证码模板形式:验证码${code},您正在进行身份验证,打死不要告诉别人哦!

    通知类消息模板:尊敬的${name}用户,恭喜您成功注册为本商城的会员用户,相信本商城会为您带来良好的体验效果,祝您生活愉快!

    推广短信模板:短信测试,短信测试,短信测试,短信测试,短信测试,短信测试

    (注:推广短信模板无需参数,其他两个均需要)

    (注意:以下方法基本放在service层)

一、开发前准备

    1、下载SDK工具包

    SDK工具包中一共包含了2个类库,一个aliyun-java-sdk-core包,另外一个是alicom-dysms-api包,将这两个包执行mvn package命令或者mvn deploy命令打包出相应的jar包,添加到工程类库中依赖使用。

    SDK&DEMO[下载地址]

二、编写代码

    1、编写短信统一处理函数

    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; }

     2、发送验证码(需要调用上面的方法)

  /**
     * @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;
    }

 

    3、发送通知类短信或推广短信

    此处使用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(); } } }); }

    (注意:如果无需同步、异步,根据自身的需求更改代码)