服务端基础设施开发----阿里大鱼短信的整合

前言

短信发送插件是很多程序都必须的一个模块,这里示范整合阿里大鱼的短信发送插件。

阿里大鱼有相关的整合教程,大家可以看看,而且这个是需要到阿里申请的收费服务。

这次整合到FileServerWebApp模块中。

添加对应的配置类以及工具类

在WebExt下面添加对应的类,如下图:
在这里插入图片描述

代码分别是:

package net.w2p.WebExt.config;

public class DaYuConf {

    public Boolean available=false;
    public String accessKeyId ;
    public  String accessKeySecret ;
    public  String signName ;

    public Boolean getAvailable() {
        return available;
    }

    public void setAvailable(Boolean available) {
        this.available = available;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getSignName() {
        return signName;
    }

    public void setSignName(String signName) {
        this.signName = signName;
    }
}

package net.w2p.WebExt.Plugins;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import net.w2p.Shared.common.OpResult;
import net.w2p.Shared.common.ValidateUtils;

import net.w2p.WebExt.config.DaYuConf;
import org.apache.commons.lang.StringUtils;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created on 17/6/7.
 * 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过
 * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
 * 工程依赖了2个jar包(存放在工程的libs目录下)
 * 1:aliyun-java-sdk-core.jar
 * 2:aliyun-java-sdk-dysmsapi.jar
 *
 * 备注:Demo工程编码采用UTF-8
 * 国际短信发送请勿参照此DEMO
 */

public class DayuSmsPlugin {

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";

    static Properties props = new Properties();// 参数配置

    
    private DaYuConf setting=null;

//    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
//    static final String accessKeyId ;
//    static final String accessKeySecret ;
//    static final String signName ;
//
//    static {
//
//
//        Properties config=new Properties();
//        InputStream inputStream=null;
//        try{
//            InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("conf/sms.properties");
//            InputStreamReader is=new InputStreamReader(in,"utf-8");
//            config.load(is);
//            is.close();
//            in.close();
//        }
//        catch (Exception ed){
//
//            ed.printStackTrace();
//        }
//        if(config!=null){
//            accessKeyId =  config.getProperty("sms.AccessKeyId");
//            accessKeySecret =  config.getProperty("sms.AccessKeySecret");
//            signName =  config.getProperty("sms.SignName");
//        }
//        else{
//            accessKeyId="";
//            accessKeySecret="";
//            signName="";
//        }
//    }


    public DayuSmsPlugin(DaYuConf setting){

        this.setting=setting;
    }



    

    private SendSmsResponse sendOriginSms(String phoneNumbers, String smsId, HashMap<String, String> paras) throws ClientException {
        HashMap<String,String> realParas=new HashMap<String, String>();
        if(paras!=null&&paras.size()>0){
            Iterator<Map.Entry<String,String>> iter = paras.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String,String> entry = (Map.Entry<String,String>) iter.next();
                String key = entry.getKey();
                String val = entry.getValue();
                if(!ValidateUtils.isEmpty(val)){
                    realParas.put(key,val);
                }
            }
        }
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", setting.accessKeyId, setting.accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(phoneNumbers);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(setting.signName);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(smsId);
        String json_parastr= JSONObject.toJSONString(realParas);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam(json_parastr);

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        request.setOutId("yourOutId");
        //hint 此处可能会抛出异常,注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        return sendSmsResponse;
    }


    public OpResult sendSms(ArrayList<String> phoneNumbers, String smsId, HashMap<String, String> paras) throws ClientException {

        OpResult opResult=new OpResult();


        if(!setting.available){
            return opResult.setError("短信服务已关闭,请通知管理员开启短信服务!");
        }
        
        String realPhoneNumbers= StringUtils.join(phoneNumbers,",");

        SendSmsResponse sendSmsResponse = sendOriginSms(realPhoneNumbers, smsId, paras);
        if(sendSmsResponse.getCode().equals("OK")){
            opResult.setSuccess(sendSmsResponse.getMessage());
        }
        else{
            opResult.setError(sendSmsResponse.getMessage());
        }

        return opResult;
    }


    public OpResult sendSms(String[] phoneNumbers, String smsId, HashMap<String, String> paras) throws ClientException {

        OpResult opResult=new OpResult();
        ArrayList<String> phones=new ArrayList<String>();
        for(String item:phoneNumbers){
            phones.add(item);
        }
        opResult=sendSms(phones,smsId,paras);
        return opResult;
    }

    public OpResult sendSms(String phoneNumber, String smsId, HashMap<String, String> paras) throws ClientException {

        OpResult opResult=new OpResult();
        ArrayList<String> phones=new ArrayList<String>();

            phones.add(phoneNumber);

        opResult=sendSms(phones,smsId,paras);
        return opResult;
    }

    private QuerySendDetailsResponse querySendDetails(String phoneNumbers,String bizId) throws ClientException {

        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", setting.accessKeyId, setting.accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象
        QuerySendDetailsRequest request = new QuerySendDetailsRequest();
        //必填-号码
        request.setPhoneNumber(phoneNumbers);
        //可选-流水号
        request.setBizId(bizId);
        //必填-发送日期 支持30天内记录查询,格式yyyyMMdd
        SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
        request.setSendDate(ft.format(new Date()));
        //必填-页大小
        request.setPageSize(10L);
        //必填-当前页码从1开始计数
        request.setCurrentPage(1L);

        //hint 此处可能会抛出异常,注意catch
        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);

        return querySendDetailsResponse;
    }

    public void main(String[] args) throws ClientException, InterruptedException {

        HashMap<String,String> paras=new HashMap<String, String>();
        paras.put("code","4457");
        //发短信
        SendSmsResponse response = sendOriginSms("你的电话号码", "短信id", paras);
        System.out.println("短信接口返回的数据----------------");
        System.out.println("Code=" + response.getCode());
        System.out.println("Message=" + response.getMessage());
        System.out.println("RequestId=" + response.getRequestId());
        System.out.println("BizId=" + response.getBizId());

        Thread.sleep(3000L);

        //查明细
        if(response.getCode() != null && response.getCode().equals("OK")) {
            QuerySendDetailsResponse querySendDetailsResponse = querySendDetails("你的电话号码",response.getBizId());
            System.out.println("短信明细查询接口返回数据----------------");
            System.out.println("Code=" + querySendDetailsResponse.getCode());
            System.out.println("Message=" + querySendDetailsResponse.getMessage());
            int i = 0;
            for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs())
            {
                System.out.println("SmsSendDetailDTO["+i+"]:");
                System.out.println("Content=" + smsSendDetailDTO.getContent());
                System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());
                System.out.println("OutId=" + smsSendDetailDTO.getOutId());
                System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());
                System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());
                System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());
                System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());
                System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());
            }
            System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());
            System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());
        }

    }
}


初始化配置中心的数据

请执行

create or replace function "initDayuSmsConfig"(
in envName varchar
)
returns varchar
as $BODY$
  declare _defaultValues varchar;
  declare _envName varchar;
  declare _appname varchar;
  declare _prefix varchar;
  declare strArrays varchar[];

  declare arrItemLv1 varchar;
  declare tempArrSubItem varchar;
  declare valArrs varchar[];

  declare item_attr varchar;
  declare item_title varchar;
  declare item_val varchar;
  declare _appDesc varchar;
  begin

    if envName <> 'test' and envName<> 'ppe' and envName<> 'product' then

      raise notice '环境变量异常,只能为test、ppe以及product其中一个。';
      return '环境变量异常,只能为test、ppe以及product其中一个。';

    end if;

    _appname:='dayu_sms';
    _appDesc:='阿里大鱼短信服务(系统通用)';
    _prefix:=concat(_appname,'.','');
  _defaultValues:=
    'available->是否启用短信服务->true$$' ||
    'accessKeyId->开发者自己的AK(在阿里云访问控制台寻找)->请在阿里云访问控制台寻找$$' ||
    'accessKeySecret->开发者自己的AK(在阿里云访问控制台寻找)->请在阿里云访问控制台寻找$$' ||
    'signName->开发者自己的AK(在阿里云访问控制台寻找)->请在阿里云访问控制台寻找$$' ||

    ''
    ;

  strArrays:=string_to_array(_defaultValues,'$$');
  _envName:=envName;

--   fastdfs.connect_timeout_in_seconds = 5
--     fastdfs.network_timeout_in_seconds = 30
--     fastdfs.charset = UTF-8
--     fastdfs.http_anti_steal_token = false
--     fastdfs.http_secret_key = FastDFS1234567890
--     fastdfs.http_tracker_http_port = 80
--                                        #fastdfs.tracker_servers = tw-server:22122,10.0.11.202:22122,10.0.11.203:22122
--     fastdfs.tracker_servers = localhost:22122
--     fastdfs.visit_url = http://localhost/

--   env     varchar(100) not null,
--     key     varchar(200) not null,
--     appname varchar(100) not null,
--     title   varchar(100) not null,
--     value   varchar(2000) default NULL::character varying,

insert into xxl_conf_project (appname, title) values (_appname,_appDesc) on conflict ("appname") do nothing;
  <<loop4BigArray>>
    foreach arrItemLv1 in array  strArrays

      loop

        if char_length(arrItemLv1) < 1 then
          raise notice '空字符串无须处理';
          continue ;
        end if;
        valArrs:=string_to_array(arrItemLv1,'->');
        item_attr:=valArrs[1];
        item_title:=valArrs[2];
        item_val:=valArrs[3];

      raise notice '属性名称:%,描述:%,当前值:%',item_attr,item_title,item_val;
      raise notice '开始添加记录';
        insert into xxl_conf_node("env","key","appname","title","value")
        values (_envName,concat(_prefix,item_attr),_appname,item_title,item_val)
        on conflict ("env","key") do nothing ;

    end loop loop4BigArray;


    return envName||'环境下的'||_appName||'配置成功';
  end;

  $BODY$ language plpgsql volatile ;
-- 记住执行下面方法分别添加三个环境下的默认数据。
-- select "initDayuSmsConfig"('test');
-- select "initDayuSmsConfig"('ppe');
-- select "initDayuSmsConfig"('product');


用工具远程登录配置中心的数据库,直接执行即可:

select "initDayuSmsConfig"('test');
select "initDayuSmsConfig"('ppe');
select "initDayuSmsConfig"('product');

使用java代码整合到spring中进行设置

在FileServerWebApp中整合。

BeanConfiguration下面添加:

package net.w2p.local.plugins.BeanConfiguration;

import com.xxl.conf.core.XxlConfClient;
import com.xxl.conf.core.listener.XxlConfListener;
import net.w2p.Shared.common.WebTools;
import net.w2p.WebExt.Plugins.DayuSmsPlugin;
import net.w2p.WebExt.config.DaYuConf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/****
 *
 * 整合阿里大鱼短信服务
 *
 * ****/
@Configuration
public class DayuSmsConfiguration {
    @Bean(name="smsConf")
    public DaYuConf smsConf(){
        final String  VarPrefix ="dayu_sms.";
        final DaYuConf conf=new DaYuConf();
        conf.available = XxlConfClient.getBoolean(VarPrefix+"available");
        conf.signName = XxlConfClient.get(VarPrefix+"signName");
        conf.accessKeySecret = XxlConfClient.get(VarPrefix+"accessKeySecret");
        conf.accessKeyId = XxlConfClient.get(VarPrefix+"accessKeyId");
        //--检测available变化:
        XxlConfClient.addListener(VarPrefix+"available", new XxlConfListener(){
            @Override
            public void onChange(String key, String value) throws Exception {
//                System.out.println("配置变更事件通知:{"+key+"}={"+value+"}");
                conf.available= WebTools.toBoolean(value);
            }
        });
        return conf;
    }

    @Bean(name="smsPlugin")
    @Autowired
    public DayuSmsPlugin smsPlugin(@Qualifier("smsConf") DaYuConf conf){
        try {
            DayuSmsPlugin plugin = new DayuSmsPlugin(conf);
            return plugin;
        }
        catch (Exception ed){
            ed.printStackTrace();
            return null;
        }
    }
}

WebTools.toBoolean 代码如下:

public class WebTools{
    public static Boolean toBoolean(Object obj){
        if(obj==null){
            return Boolean.FALSE;
        }

        String str=obj.toString().trim().toLowerCase();

        if(str.equals("1")||str.equals("true")){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}

进行测试

测试代码如下:

package other;

import com.alibaba.fastjson.JSONObject;
import main.BaseTest;
import net.w2p.Shared.common.OpResult;
import net.w2p.WebExt.Plugins.DayuSmsPlugin;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;

public class ExtComponentTest extends BaseTest {

    @Autowired
    DayuSmsPlugin smsPlugin;

    @Test
    public void testSendSMS() throws Exception {
        String random_code             ="123456";
        String mobile                  =                  "发送短信的电话号码,最好是自己手机";
        String smsId =                                   "SMS_xxxxx【sms模板id】";
        HashMap<String,String> paras=
                new HashMap<String, String>();
        paras.put("code", random_code);


        OpResult opResult=smsPlugin.
                sendSms(mobile,smsId,paras);
        System.out.println
                (JSONObject.toJSONString(opResult));
    }
}

测试结果:

在开启服务情况下:

在这里插入图片描述

在设置服务关闭下:
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值