# 一、短信服务
好的第三方短信服务平台要具备一下五点:
到达率高
功能齐全
短信价格合理
售后服务完善
信誉好
介于目前业界口碑排行,最终选择阿里云短信平台。
# 二、阿里云短信平台
# 2.1 阿里SMS简介
短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力。调用API或用群发助手,即可发送验证码、通知类和营销类短信;国内验证短信秒级触达,到达率最高可达99%;国际/港澳台短信覆盖200多个国家和地区,安全稳定,广受出海企业选用。
短信平台网址:
阿里云短信服务官网API文档:
https://next.api.aliyun.com/document/Dysmsapi/2017-05-25/overview (opens new window)
# 2.2 产品优势
快速稳定:3秒可达,99%到达率,国内短信与工信部携号转网平台实时互联。
接入便捷:群发助手,简单便捷。API和多语言SDK接入,有效节约开发时间与成本。
智能监控调度:电信级运维保障,实时监控、自动切换,确保发送成功率。
高并发:高效的调度算法解决高峰时段的业务压力。
# 2.3 阿里云配置SMS
# 开通阿里云账户
开通阿里云账户https://www.aliyun.com (opens new window)
# 购买短信套餐包
在阿里云平台搜索短信服务,进行购买短信套餐包。
阿里云SMS短信平台购买方案 | ||
---|---|---|
资源包规格 | 购买时长(月) | 价格(元) |
1000条 | 24个月 | 50 |
2000条 | 24个月 | 100 |
5000条 | 24个月 | 180 |
1.5万条 | 24个月 | 705 |
5万条 | 24个月 | 2150 |
20万条 | 24个月 | 8064 |
表1-1短信套餐包
# 获取AccessKeyID和密钥
AccessKey ID和AccessKey Secret是您访问阿里云API的密钥,具有该账户完全的权限,请您妥善保管。
为了安全起见,请使用子用户AccessKey。
获取AccessKey:https://ram.console.aliyun.com/users/new (opens new window)
# 申请签名
签名是短信中能代表发送者属性的字段。
添加签名:https://dysms.console.aliyun.com/domestic/text/sign/add (opens new window)
# 申请模板
模板即具体发送的短信内容。
申请模板:https://dysms.console.aliyun.com/domestic/text/template/add (opens new window)
# 系统设置
系统设置:https://dysms.console.aliyun.com/general (opens new window)
# 2.4 SDK接入(旧版)
环境要求
最低要求Java 8
安装 SDK 核心库 OpenAPI ,可以通过 POM 文件引入的方式来安装。
https://help.aliyun.com/document_detail/55284.htm
# 代码开发
# 配置yml
#短信配置信息
message:
ali_message:
ali_accessKey_Id: LTAIlz8rCF976lQ
ali_accessKey_Secret: HDtzEAUIplSXT2czrasr2DvC40
# 通知的短信签名
signName_inform: xxx科技有限公司
# 通知的短信模板
templateCode_inform: SMS_158345131
2
3
4
5
6
7
8
9
# 引入SDK
<properties>
<aliyun-java-sdk-core.version>3.3.1</aliyun-java-sdk-core.version>
<aliyun-java-sdk-dysmsapi.version>1.0.0</aliyun-java-sdk-dysmsapi.version>
</properties>
<!-- 短信服务 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>${aliyun-java-sdk-dysmsapi.version}</version>
</dependency>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 发送短信API
@Component
@Data
public class MessageProperties {
/**
* 阿里云API的密钥
*/
@Value("${message.ali_message.ali_accessKey_Id}")
private String aliAccessKeyId;
@Value("${message.ali_message.ali_accessKey_Secret}")
private String aliAccessKeySecret;
/**
* 短信签名
*/
@Value("${message.ali_message.signName_inform}")
private String signNameInform;
/**
* 短信模板 - 注册验证码
*/
@Value("${message.ali_message.templateCode_inform}")
private String templateCodeInform;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
封装对象
public class SmsDTO implements Serializable {
private static final long serialVersionUID = 3712925418243796538L;
/**
* 短信签名名称
*/
private String signNameInform;
/**
* 短信模板CODE
*/
private String templateCodeInform;
/**
* 接收短信的手机号码
*/
private String phoneNumbers;
/**
* 发送短信内容
*/
private String content;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 阿里云短信服务工具类
@Component
@Slf4j
public class SmsUtils {
@Autowired
private MessageProperties resourcesProperties;
/**
* 发送短信
* @param phoneNum 必填:待发送手机号
* @param signName 必填:短信签名,传入的短信签名必须是在阿里云“管理中心-短信签名管理”中的可用签名
* @param templateCode 必填:短信模板ID,传入的模板必须是在阿里云“管理中心-短信模板管理”中的可用模板。示例:SMS_585014
* @param templateParam 可选:模板中的变量替换JSON串
* @return
* @throws ClientException
*/
public String sendMsg(String phoneNum, String signName, String templateCode, String templateParam ) throws ClientException {//拿到手机号
//调用阿里通信接口
//设置超时时间-可自行调整
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(在阿里云访问控制台寻找)
//你的accessKeyId,
final String accessKeyId = resourcesProperties.getAliAccessKeyId();
//你的accessKeySecret,
final String accessKeySecret = resourcesProperties.getAliAccessKeySecret();
//初始化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个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
request.setPhoneNumbers(phoneNum);
//必填:短信签名-可在短信控制台中找到
request.setSignName(signName);
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCode);
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
//生成几位的验证码
// String numeric = RandomStringTLUtils.randomNumeric(6);
if(StringUtils.isNotBlank(templateParam)){
request.setTemplateParam(templateParam);
}
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
// request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
// request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = new SendSmsResponse();
try {
sendSmsResponse = acsClient.getAcsResponse(request);
} catch (Exception e) {
log.error(e.getMessage());;
}
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
//真实应用的时候验证码在服务端有记录
//客户端由客户来输入
//客户输入的验证码和服务端做匹配
return sendSmsResponse.getCode();
}
return "error";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 接收数据接口
public class AliyunSmsSend {
/**
* 发送短信 - 注册功能发送短信验证码
*
* @param smsDTO
* @date 2022/4/13 17:43
* @author superC
*/
public static void sendSms2Register(SmsDTO smsDTO) {
try {
//模板中的变量替换JSON串(code为模板中的变量)
String templateParam = "{\"code\":\"" + smsDTO.getContent() + "\"}";
String result = SmsUtils.sendMessage(smsDTO.getPhoneNumbers(), smsDTO.getSignNameInform(), smsDTO.getTemplateCodeInform(), templateParam);
logger.debug("发送短信结果:{}", result);
} catch (ClientException e) {
logger.error("【捕获发送短信异常】\r\n异常记录:", e);
;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2.5 SDK接入(新版)
# 1、短信服务使用
- 身份管理→用户→权限管理,添加用户操作权限;
- 创建用户 AccessKey及密钥;
- 购买短信服务套餐;
- 申请签名;
- 申请模板;
# 2、短信服务测试
https://dysms.console.aliyun.com/quickstart
每个账号限制授权5个测试手机号
测试专用模版只支持4-6位纯数字、测试专用签名+模版只能结合使用。
# 测试专用签名
- 签名名称:阿里云短信测试
- 使用场景:发送测试短信
# 测试专用模版
- 模版名称:测试专用模板
- 模版Code:SMS_154950909
- 模版类型:验证码
- 模版内容:您正在使用阿里云短信测试服务,体验验证码是:${code},如非本人操作,请忽略本短信!
# 3、代码开发
# 配置文件
base:
config:
aliyun:
sms:
endpoint: dysmsapi.aliyuncs.com
accesskeyId: 你的AccessKey-ID
accesskeySecret: 你的AccessKey-Secret
signNameInform: 阿里云短信测试
# 短信模板
templateCodeInform:
loginCaptcha: SMS_154950909
2
3
4
5
6
7
8
9
10
11
# 引入SDK
<properties>
<aliyun-sms.version>2.0.9</aliyun-sms.version>
</properties>
<!-- ******** 短信服务-新版SDK Begin ********** -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>${aliyun-sms.version}</version>
</dependency>
<!-- ******** 短信服务-新版SDK End ********** -->
2
3
4
5
6
7
8
9
10
11
# 发送短信API
/**
* 单条短信发送
*
* @param client 调用AliyunSmsBase.createClient()创建
* @param phoneNumbers 接收短信的手机号码,多个用英文逗号隔开
* @param signName 短信签名名称,eg: "阿里云"
* @param templateCode 短信模板CODE
* @param templateParam 短信模板变量对应的实际值,eg:{"code":"1234"}
* @return sendResp.body.bizId可用于查询短信发送结果
* @throws Exception
*/
public static SendSmsResponse send(Client client, String phoneNumbers, String signName, String templateCode, String templateParam) throws Exception {
SendSmsRequest sendReq = new SendSmsRequest()
.setPhoneNumbers(phoneNumbers)
.setSignName(signName)
.setTemplateCode(templateCode)
.setTemplateParam(templateParam);
return client.sendSms(sendReq);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19