1. 功能设置
a. 首先在阿里云平台开通短信服务功能:
b. 在平台上,进行短信签名设置,短信签名需要平台人工审核:
c. 进行短信模板设置,以验证码为例:
其中的code为变量,是程序传入的参数;
短信模板申请,需要人工审核,大概两个小时左右。
2. 短信功能实现
a. 在pom文件中,添加依赖:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
b. 创建 AliYunProperties 文件:
package com.common.properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 根据环境,读取阿里云配置环境信息
* admin 2021/8/16 09:47
*/
@Component
public class AliYunProperties {
public static String accessKeyId;
public static String accessKeySecret;
public static String endpoint;
public static String domain;
@Value("${aliyun.accessKeyId}")
public void setAccessKeyId(String accessKeyId) {
AliYunProperties.accessKeyId = accessKeyId;
}
@Value("${aliyun.accessKeySecret}")
public void setAccessKeySecret(String accessKeySecret) {
AliYunProperties.accessKeySecret = accessKeySecret;
}
@Value("${aliyun.endpoint}")
public void setEndpoint(String endpoint) {
AliYunProperties.endpoint = endpoint;
}
@Value("${aliyun.domain}")
public void setDomain(String domain) {
AliYunProperties.domain = domain;
}
}
c. 在yml文件中,添加对应配置信息:
aliyun:
accessKeyId: 你的key
accessKeySecret: 你的secret
endpoint: oss-cn-hangzhou.aliyuncs.com
domain: dysmsapi.aliyuncs.com
d. 创建短信工具类:
package com..common.util;
import com.alibaba.fastjson.JSON;
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.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.louwen.hpr.common.exception.service.ServiceException;
import com.louwen.hpr.common.properties.AliYunProperties;
import lombok.extern.slf4j.Slf4j;
/**
* 短信工具类
* admin 2021/8/20 9:59
*/
@Slf4j
public class SmsUtil {
private static String domain;
private static String accessKeyId;
private static String accessKeySecret;
static {
domain = AliYunProperties.domain;
accessKeyId = AliYunProperties.accessKeyId;
accessKeySecret = AliYunProperties.accessKeySecret;
}
/***
* 发送短信
* @param smsId 短信模板编号 短信模板-可在短信控制台中找到
* @param paramJson 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
* JSONObject object = new JSONObject();
* object.put("name", "科技");
* object.put("code", 1234);
*
* 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,
* 比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
* @param phoneNumbers 要发送的电话号码,上限1000
* @param signName 短信签名
* @return 发送结果
*/
public static String send(String smsId, String paramJson, String signName, String... phoneNumbers) throws ClientException {
IAcsClient acsClient = getInstance();
SendSmsRequest request = new SendSmsRequest();
request.setMethod(MethodType.POST);
request.setPhoneNumbers(getPhone(phoneNumbers));
request.setSignName(signName);
request.setTemplateCode(smsId);
request.setTemplateParam(paramJson);
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
log.info("短息发送成功,接受手机号码为:{}", (Object) phoneNumbers);
return null;
} else if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("isv.BUSINESS_LIMIT_CONTROL")) {
return "短信发送过于频繁,请稍后再试";
} else if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("isv.MOBILE_NUMBER_ILLEGAL")) {
return "无效的手机号码";
}
log.error("短信发送失败:{}", JSON.toJSONString(sendSmsResponse));
return "短信发送失败";
}
/***
* 拼接手机号
*/
private static String getPhone(String... phoneNumbers) {
if (phoneNumbers == null || phoneNumbers.length < 1) {
throw new ServiceException("发送号码不能为空");
}
if (phoneNumbers.length > 1000) {
throw new ServiceException("发送号码最多1000个");
}
//世界最长号码 00+国际区号+号码 = 16 + 逗号 = 17,避免扩容导致性能问题
StringBuilder phone = new StringBuilder(phoneNumbers.length * 17);
for (String p : phoneNumbers) {
phone.append(p).append(",");
}
return phone.deleteCharAt(phone.length() - 1).toString();
}
private static IAcsClient getInstance() {
System.setProperty("sun.net.client.defaultConnectTimeout", "1000");
System.setProperty("sun.net.client.defaultReadTimeout", "1000");
//短信API产品名称(短信产品名固定,无需修改)
String product = "Dysmsapi";
String endpoint = "cn-hangzhou";
String region = "cn-hangzhou";
IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
try {
DefaultProfile.addEndpoint(endpoint, region, product, domain);
} catch (ClientException e) {
log.error("阿里大于短信工具初始化错误", e);
}
return new DefaultAcsClient(profile);
}
}
3. 短信功能调用
a. 一般在实际应用中,我们在业务service层去进行调用,举例说明:
public void sendSmsMsg(String mobile, String smsCode, String templateCode, JSONObject jsonObject) throws ClientException {
String result = SmsUtil.send(smsCode, jsonObject.toJSONString(), SmsConstants.SEND_SMS_MSG_SIGN_NAME, mobile);
if (StringUtils.isNotEmpty(result)) {
throw new ServiceException(result);
}
}
JSONObject object = new JSONObject();
object.put("customer", adInfo.getCustomerName());
object.put("count", getAdMaxDistributeCount(adInfo.getAdNo()));
msgRpcService.sendSmsMsg(adInfo.getConcatMobile(), SmsConstants.AD_REVIEW_SUCCESS,
MsgConstant.SEND_AD_REVIEW_SUCCESS, object);
以上,就是阿里云短信在Java服务端的应用。
你的努力,终将成为你最有力的资本!