前言
短信发送插件是很多程序都必须的一个模块,这里示范整合阿里大鱼的短信发送插件。
阿里大鱼有相关的整合教程,大家可以看看,而且这个是需要到阿里申请的收费服务。
这次整合到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&¶s.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));
}
}
测试结果:
在开启服务情况下:
在设置服务关闭下: