技术干货实战(7)- Spring Boot2.x实战实现阿里云SMS短信发送功能

作者: 修罗debug
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。


“短信发送”功能在企业应用系统开发中应该说算是很常见的了,典型的案例 如 “用户登录时可以通过手机号接收平台发送的验证码进行登录”、“用户通过手机号接收平台发送的短信验证码从而找回密码”、“双重验证用户身份时需要用手机号接收平台发送的验证码已确认用户身份”等等都是比较常见的,本文将基于阿里云SMS短信发送服务 在Java Spring Boot应用系统实现短信发送功能


移动互联网时代,几乎人人都有部智能手机,每天的收、发短信操作想必已成常态,在使用各种APP或者网站应用系统时相比也应该经常都能有所见闻;而作为一名Java开发者,不知诸位在实际项目、实际应用系统中是否有真正地实现过短信发送以及对短信验证码进行验证的功能?今天debug将带大家一起实战落地该功能!


顺带提下,我们将基于Spring Boot2.x进行代码实战,别问为什么哈!作为一名Java开发者,如果都不知道Spring Bootdebug都不知道该怎么说你了!另外,我们将基于阿里云SMS短信发送服务功能,其官网如下所示:https://www.aliyun.com/product/sms ,可以点击购买或者免费开通,如果人品好的话,估计还真的可以免费开通(免费试用几条);



在这里,debug就假设诸位已经成功开通了阿里云SMS短信发送服务了哈(如果没有开通成功也没关系,收藏下文章吧,以后总有用得着的),OK,话不多说,咱们直接开干!


1)首先,需要加入阿里云短信SMS服务的SDK,即对于我们Java后端而言,其实就是一个Jar包,如下所示:   

<!--阿里云短信服务-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.0</version>
</dependency>

2)紧接着是进入阿里云短信服务管理控制台,获取AccessKey ID AccessKey Secret并创建“短信签名”以及“短信发送模板”,如下图所示:




拿到这些信息之后,接下来需要将这些信息项配置起来,如下所示:   

#阿里云sms配置
ali.sms.accessKeyId=这里是你的AccessKey ID
ali.sms.accessSecret=这里是你的AccessKey Secret
ali.sms.regionId=cn-hangzhou
ali.sms.sysDomain=dysmsapi.aliyuncs.com
ali.sms.sysVersion=2017-05-25
ali.sms.sysAction=SendSms
ali.sms.enabled=true

ali.sms.phone.sendCode.bu=申请的短信签名
ali.sms.phone.sendCode.temp=申请的短信模板编码
ali.sms.phone.sendCode.msg=备注信息


之后便可以基于Spring Boot自动注入配置的功能特性将以上配置项加入到一个实体类中,以方便后续开发实际业务代码时使用,其定义如下所示:   

@Configuration
@ConfigurationProperties(prefix = "ali.sms")
@Data
public class AliSmsProperty {
private String accessKeyId;

private String accessSecret;

private String regionId;

private String sysDomain;

private String sysVersion;

private String sysAction;

private Boolean enabled;
}


3)紧接着,开发调用阿里云短信服务SMSSDK提供的发送短信功能 的代码,如下所示:   

@Service
public class AliSmsService {
private static final Logger log= LoggerFactory.getLogger(AliSmsService.class);

private static final String Channel="aliyun";

@Autowired
private AliSmsProperty aliSmsProperty;

@Autowired
private ObjectMapper objectMapper;

//发送通用消息
public void sendMsg(AliSmsRequest smsRequest,final Long sendId) throws Exception{
if (!aliSmsProperty.getEnabled()){
return;
}

//参数校验

//短信配置初始化
DefaultProfile profile=DefaultProfile.getProfile(aliSmsProperty.getRegionId(),aliSmsProperty.getAccessKeyId(),aliSmsProperty.getAccessSecret());
IAcsClient client=new DefaultAcsClient(profile);
//构造短信发送请求
CommonRequest request=new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain(aliSmsProperty.getSysDomain());
request.setSysVersion(aliSmsProperty.getSysVersion());
request.setSysAction(aliSmsProperty.getSysAction());

request.putQueryParameter("RegionId", aliSmsProperty.getRegionId());
request.putQueryParameter("PhoneNumbers", smsRequest.getPhoneNumbers());
request.putQueryParameter("SignName", smsRequest.getSignName());
request.putQueryParameter("TemplateCode", smsRequest.getTemplateCode());
request.putQueryParameter("TemplateParam", smsRequest.getTemplateParam());

request.putQueryParameter("SmsUpExtendCode", RandomStringUtils.randomNumeric(4));
request.putQueryParameter("OutId", smsRequest.getTemplateCode()+"_"+RandomStringUtils.randomAlphanumeric(8));

//发送短信
CommonResponse response = client.getCommonResponse(request);
log.info("--阿里云短信发送结果:{},{},{}----",response.getHttpStatus(),response.getHttpResponse(),response.getData());

if (response!=null && StringUtils.isNotBlank(response.getData())){
AliSmsResponse smsResponse=objectMapper.readValue(response.getData(),AliSmsResponse.class);
if (smsResponse!=null && "OK".equals(smsResponse.getCode())){
//创建一条短信发送成功的记录(记录到数据库DB,以用于后续的验证码验证)

}else{
//创建一条短信发送失败的记录
}
}
}
}


其中,AliSmsRequest为开放给客户端调用的参数,其定义如下所示:   

@Data
public class AliSmsRequest implements Serializable{
//要接受短信的手机号
private String phoneNumbers;

//申请的短信签名
private String signName;

//申请的模板编码
private String templateCode;

//短信发送参数-json格式的字符串,如{"code":123456}
private String templateParam;

//短信发送上行编码-按照官方建议的填就行
private String smsUpExtendCode;
//序列id-按照官方建议的填就行
private String outId;

public AliSmsRequest(String phoneNumbers, String signName, String templateCode, String templateParam) {
this.phoneNumbers = phoneNumbers;
this.signName = signName;
this.templateCode = templateCode;
this.templateParam = templateParam;
}

public AliSmsRequest() {
}
}


至此,我们已经将发送短信的核心代码撸完了,其中传递给服务端的参数的格式为(以发送短信验证码为例):   

{
"phoneNumbers":"15812490898",
"signName":"申请的短信签名",
"tempCode":"申请的短信模板编码",
"templateParam":"{\"code\":\"708946\"}",
"smsUpExtendCode":"12345678",
"outId":"12345678"
}


如果过程没有报错,不出5秒应该会受到一条短信,如下图所示:


OK,打完收工,咱们下期再见!

总结:

我是debug,一个相信技术改变生活、技术成就梦想 的攻城狮;如果本文对你有帮助,请关注公众号,并动动手指收藏、点赞、以及转发哦!!!