Spring Boot整合阿里云SMS短信服务实现高效通信
在数字化时代,短信服务成为了企业与客户沟通的重要桥梁。阿里云SMS短信服务以其稳定、可靠的性能和丰富的功能,成为了众多企业的首选。本文将带您深入了解阿里云SMS短信服务,探索其优势与应用场景。
一、短信服务介绍
短信服务(Short Message Service)是阿里云为广大企业用户或个人用户提供的通信服务。通过API/SDK、控制台调用短信发送能力,将指定信息发送至国内或境外手机号码。您可以在不同场景发送不同类型的短信,例如验证码、通知短信、推广短信以及多媒体短信等,给您带来安全可靠的服务体验。
优势
- 稳定性高:阿里云SMS具有高度的稳定性和可靠性,能够确保短信发送的及时性和准确性。
- 可扩展性强:阿里云SMS支持高并发、大容量的短信发送需求,能够满足企业快速增长的业务需求。
- 安全性好:阿里云SMS采用多重安全机制,确保短信发送过程的安全性和隐私性。
- 灵活性强:阿里云SMS支持多种短信发送方式,如单条发送、批量发送、定时发送等,能够满足企业不同的业务需求。
- 易于集成:阿里云SMS提供完善的API/SDK支持,开发者可以方便地将短信服务集成到Spring Boot项目中,实现快速开发和部署。
使用场景
- 验证码:用于App、网站的账号注册、登录账户、找回密码等场景的安全验证。
- 短信通知:向注册用户下发系统相关信息,如升级或维护、服务开通、价格调整、订单确认、物流动态、消费确认、支付通知等。
- 推广短信:向注册用户和潜在客户发送通知和推广信息,如促销活动通知、业务推广、新产品宣讲、会员关怀等。
- 多媒体短信:向手机号码发送包含文本、图片、音频、视频的短信,短信内容为经过审核的模板内容。
二、阿里云平台使用说明
1.登录阿里云平台,若没有账号可以先注册
2.搜索短信服务
3.注册相关信息
- 资质
- 签名
- 模版
4.添加并牢记自己的 Access Key
三、API接口说明
接口说明
- 针对国内短信服务超时的时间建议设置≥1S。
- SDK 重试默认是开启的,建议关闭不要打开重试;发生超时失败的情况,建议等待回执状态再决定是否重试;
- 国内短信、国际短信和多媒体消息,均不支持幂等的能力,请您自行做好幂等控制。
- 本接口主要适用于短信单发场景,特殊场景下可支持群发(最多可向 1000 个手机号码发送同样内容的短信),但群发会有一定延迟。
- 如果您需要在一次请求中分别向多个不同的手机号码发送不同签名和模板内容的短信,请使用 SendBatchSms 接口。
发送短信会根据发送量计费,价格请参见 计费说明。 - 当您的验证码签名和通用签名,名称相同时系统默认使用通用签名发送短信。
流控信息
请求速率为5000/1(s)。更多流控信息,请前往配额中心查看
请求参数
- PhoneNumbers string: 接收短信的手机号码。 示例值:
1390000****
- SignName string: 短信签名名称。 示例值:
阿里云
- TemplateCode string: 短信模板 Code。 示例值:
SMS_15305****
- TemplateParam string: 信模板变量对应的实际值,支持传入多个参数。 示例值:
{"name":"张三","number":"1390000****"}
- SmsUpExtendCode string: 上行短信扩展码。上行短信指发送给通信服务提供商的短信,用于定制某种服务、完成查询,或是办理某种业务等,需要收费,按运营商普通短信资费进行扣费。 示例值:
90999
- OutId string: 外部流水扩展字段。 示例值:
abcdefgh
返回参数
- Code string: 请求状态码。1.返回OK代表请求成功。 2.其他错误码,请参见 API错误码。 示例值:
OK
- Message string: 状态码的描述。 示例值:
OK
- BizId string: 发送回执 ID。可根据发送回执 ID 在接口 QuerySendDetails 中查询具体的发送状态。 示例值:
9006197469364984****
- RequestId: 请求 ID。 示例值:
F655A8D5-B967-440B-8683-DAD6FF8DE990
四、实例代码
发送前请申请短信签名和短信模板,并确保签名和模板已审核通过。
1.在pom.xml
中引入依赖
<!-- 阿里云短信服务依赖,作用是发送短信验证码 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.16</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.1.0</version>
</dependency>
2.短信发送工具类
package com.ljh.springboot3.utils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
/**
* @author Mr.Liu
* @version 1.0
* @description: 短信工具类
*/
public class SMSUtil {
/**
* 发送短信
*
* @param signName 签名
* @param templateCode 模板
* @param phoneNumbers 手机号
* @param param 参数
*/
public static void sendMessage(String signName, String templateCode, String phoneNumbers, String param) {
/*
这三个需要自己填写
cn-hangzhou:服务地区,选择距离自己近的,我选择的是cn-hangzhou
AccessKey ID:访问阿里云 API 的Id
AccessKey Secret:Id对应的密钥,具有该账户相应的权限
*/
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "AccessKey ID", "AccessKey Secret");
IAcsClient client = new DefaultAcsClient(profile);
SendSmsRequest request = new SendSmsRequest();
request.setSysRegionId("cn-hangzhou");
request.setPhoneNumbers(phoneNumbers);
request.setSignName(signName);
request.setTemplateCode(templateCode);
request.setTemplateParam("{\"code\":\"" + param + "\"}");
try {
SendSmsResponse response = client.getAcsResponse(request);
} catch (ClientException e) {
e.printStackTrace();
}
}
}
3.创建验证码生成工具类
package com.ljh.springboot3.utils;
import java.util.Random;
/**
* @author Mr.Liu
* @version 1.0
* @description 验证码工具类
*/
public class ValidateCodeUtil {
/**
* 随机生成验证码
* @param length 长度为4位或者6位
* @return
*/
public static Integer generateValidateCode(int length){
Integer code =null;
if(length == 4){
code = new Random().nextInt(9999);//生成随机数,最大为9999
if(code < 1000){
code = code + 1000;//保证随机数为4位数字
}
}else if(length == 6){
code = new Random().nextInt(999999);//生成随机数,最大为999999
if(code < 100000){
code = code + 100000;//保证随机数为6位数字
}
}else{
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
/**
* 随机生成指定长度字符串验证码
* @param length 长度
* @return
*/
public static String generateValidateCode4String(int length){
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
String capstr = hash1.substring(0, length);
return capstr;
}
}
4.控制层
/**
* @param sendPhoneDTO 自己设定的前端传过来的类,里面至少包括手机号
*/
@PostMapping("/phone")
public Result sendPhoneLogin(@RequestBody SendPhoneDTO sendPhoneDTO) {
try {
sendService.sendPhoneLogin(sendPhoneDTO.getPhone());
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
return Result.success();
}
5.业务层接口
void sendPhoneLogin(String phone);
6.业务层接口实现类
可以根据自己的业务需求定义不同的业务实现逻辑
@Override
public void sendPhoneLogin(String phone) {
// 校验手机号格式
if (!phone.matches(PHONE_REGEX)) {
throw new ServiceException("The phone number is in the wrong format");
}
// 校验手机号是否已发送验证码
String ValidCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
// 如果验证码已发送,则抛出异常
if (ValidCode != null) {
throw new ServiceException("The verification code has been sent to the phone number recently, please try again later");
}
// 没有验证码,则生成随机的6位验证码
String code = ValidateCodeUtil.generateValidateCode(6).toString();
// 调用阿里云提供的短信服务API完成发送短信
SMSUtil.sendMessage("自己的签名名字", "自己的模版CODE", phone, code);
// 将生成的验证码缓存到redis总共,并且设置有效期为5分钟
stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);
}