<dependencies>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<artifactId>common-server-sms</artifactId>
ruyi:
sms:
aliyun:
app-id: xxxxxxxxxxx
app-secret: xxxxxxx
sign-name: 自己设置的短信签名
#模板
templates:
#验证码模板
VALID_CODE: SMS_234234343(自己设置的)
/**
* @ClassName: AliSmsProperties
* @Description: 阿里云短信配置类
* @author: ruyi
* @date: 2021/12/27 22:45
*/
@Data
@ConfigurationProperties(prefix = "thg.sms.aliyun")
public class AliSmsProperties {
final static String DEFAULT_PRODUCT="Dysmsapi";
/**默认域名*/
final static String DEFAULT_DOMAIN="dysmsapi.aliyuncs.com";
final static String DEFAULT_REGION ="cn-hangzhou";
private String product=DEFAULT_PRODUCT;
private String domain=DEFAULT_DOMAIN;
private String regionId= DEFAULT_REGION;
private String appId;
private String appSecret;
/**短信签名*/
private String signName;
/**
* 短信模板集合
*/
private Map<String,String> templates=new HashMap<>();
}
/**
* @ClassName: SmsResponse
* @Description: 短信发送响应
* @author: ruyi
* @date: 2021/12/27 22:25
*/
@Data
public class SmsResponse {
/**
* 发送是否成功
*/
private Boolean send;
/**
* 错误消息
*/
private String msg;
public SmsResponse(Boolean send, String msg) {
this.send = send;
this.msg = msg;
}
public SmsResponse(String msg) {
this.send=Boolean.FALSE;
this.msg = msg;
}
public SmsResponse() {
this.send=Boolean.TRUE;
}
}
/**
* @ClassName: NoticeData
* @Description: 短信模板
* @author: ruyi
* @date: 2021/12/27 22:21
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class NoticeData implements Serializable{
/**
*
*/
private static final long serialVersionUID = -6624808649341355670L;
/**
* 短信模板类型
*/
private String type;
/**
* 变量参数
*/
private Map<String,String> params;
}
/**
* @ClassName: NoticeInfo
* @Description: 通知消息
* @author: wyj
* @date: 2021/12/27 22:18
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class NoticeInfo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 通知内容
*/
private NoticeData noticeData;
/**
* 号码列表
*/
private Collection<String> phones;
}
/**
* @ClassName: BaseSmsSender
* @Description: 短信发送器接口
* @author: ruyi
* @date: 2021/12/27 22:33
*/
public interface BaseSmsSender {
/**
* 单发
* @param data 发送内容
* @param mobile 发送手机
* @return
*/
default SmsResponse send(NoticeData data, String mobile) {
Assert.notNull(mobile,"mobile must be not null");
return send(data, Arrays.asList(mobile));
}
/**
* 群发
* @param data 发送内容
* @param mobile 发送手机号集合
* @return
*/
default SmsResponse send(NoticeData data, String... mobile) {
if(mobile == null) {
return new SmsResponse("手机号为空");
}
return send(data, Arrays.asList(mobile));
}
SmsResponse send(NoticeData data,Collection<String> mobiles);
}
/**
* @ClassName: AliSmsSender
* @Description: 阿里云短信发送
* @author: ruyi
* @date: 2021/12/27 22:45
*/
@Slf4j
public class AliSmsSender implements BaseSmsSender {
private IAcsClient acsClient;
private AliSmsProperties smsProperties;
private static final String OK = "OK";
public AliSmsSender(AliSmsProperties smsProperties) {
this.smsProperties = smsProperties;
initClient();
}
private void initClient() {
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
IClientProfile profile = DefaultProfile.getProfile(smsProperties.getRegionId(), smsProperties.getAppId(), smsProperties.getAppSecret());
DefaultProfile.addEndpoint(smsProperties.getRegionId(), smsProperties.getProduct(), smsProperties.getDomain());
acsClient = new DefaultAcsClient(profile);
}
private SendSmsResponse sendSms(NoticeData data, Collection<String> mobile) {
SendSmsResponse sendSmsResponse = new SendSmsResponse();
SendSmsRequest request = buildSmsRequest(data, mobile);
try {
sendSmsResponse = acsClient.getAcsResponse(request);
if (OK.equals(sendSmsResponse.getCode())) {
log.info("mobile={},data={},result={},send sms success", CollectionUtil.join(mobile, ","),JSONUtil.toJsonStr(data), sendSmsResponse.getMessage());
}else{
log.warn("mobile={},data={},result={},send sms failed", CollectionUtil.join(mobile, ","),JSONUtil.toJsonStr(data), sendSmsResponse.getMessage());
}
} catch (ClientException e) {
log.error("send sms failed:mobile={},data:{},result={},exception={}",CollectionUtil.join(mobile, ","),JSONUtil.toJsonStr(data),sendSmsResponse.getMessage(), e.getErrMsg());
throw new BizException("短信发送失败!");
}
return sendSmsResponse;
}
private SendSmsRequest buildSmsRequest(NoticeData data, Collection<String> mobile) {
SendSmsRequest request = new SendSmsRequest();
request.setSignName(smsProperties.getSignName());
request.setTemplateCode(smsProperties.getTemplates().get(data.getType()));
Map<String, String> params = data.getParams();
if (params != null && params.size() > 0) {
request.setTemplateParam(JSONUtil.toJsonStr(params));
}
request.setPhoneNumbers(CollectionUtil.join(mobile, ","));
return request;
}
@Override
public SmsResponse send(NoticeData data, Collection<String> mobiles) {
SendSmsResponse smsResponse= sendSms(data, mobiles);
if(OK.equals(smsResponse.getCode())) return new SmsResponse();
else return new SmsResponse(smsResponse.getMessage());
}
}
/**
* @ClassName: AutoAliSmsConfiguration
* @Description: 阿里云短信配置类
* @author: ruyi
* @date: 2021/12/27 22:45
*/
@Configuration
@EnableConfigurationProperties(AliSmsProperties.class)
public class AutoAliSmsConfiguration {
private final AliSmsProperties smsProperties;
public AutoAliSmsConfiguration(AliSmsProperties smsProperties) {
this.smsProperties = smsProperties;
}
/**
* If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after.
* ConditionalOnMissingBean该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean;不存在则创建
* @return 短信发送器
*/
@Bean
@ConditionalOnMissingBean(AliSmsProperties.class)
public AliSmsSender aliSmsSender() {
return new AliSmsSender(smsProperties);
}
}
注意:需要创建spring.factories 自动装配AutoAliSmsConfiguration类
在 resource文件夹创建META-INF文件夹 创建文件spring.factories加入配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.ruyi.aliyun.AutoAliSmsConfiguration
比如我在用户模块需要使用短信服务,那我只在用户服务依赖短信服务common-server-sms
<dependency>
<groupId>cn.wyj</groupId>
<artifactId>common-server-sms</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
private final AliSmsSender aliSmsSender;(用的构造注入,也可以直接自己喜欢的注入方式)
@GetMapping(value = "/send")
public SmsResponse sendSms() {
Map<String,String> content = new HashMap<>(16);
content.put("code", String.valueOf(RandomUtil.randomInt(100000, 999999)));
return aliSmsSender.send(new NoticeData(SmsConstants.CODE_KEY, content), "153****6968");
}