1)构建Springboot项目
2) 添加依赖
<!--阿里云短信-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibabacloud-dysmsapi20170525</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-idaas-doraemon</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<optional>true</optional>
<version>[4.4.9,5.0.0)</version>
</dependency>
3) 配置文件
aliyun:
sms:
accessKey: V***********y
accessSecret: e***********************z
regionId: cn-******
endPoint: dysm***.al*****.c**
4)配置类
@Component
@Slf4j
public class AliyunConstant implements InitializingBean {
@Value("${aliyun.sms.accessKey}")
public String accessKey;
@Value("${aliyun.sms.accessSecret}")
public String accessSecret;
@Value("${aliyun.sms.regionId}")
public String regionId;
@Value("${aliyun.sms.endPoint}")
public String endPoint;
public static String ACCESS_KEY;
public static String ACCESS_SECRET;
public static String REGION_ID;
public static String END_POINT;
@Override
public void afterPropertiesSet(){
ACCESS_KEY = accessKey;
ACCESS_SECRET = accessSecret;
REGION_ID = regionId;
END_POINT = endPoint;
}
/*
* 为了解决base64加密 密钥太长报错问题
*/
static {
try {
Class<?> clazz = Class.forName("javax.crypto.JceSecurity");
Field nameField = clazz.getDeclaredField("isRestricted");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL);
nameField.setAccessible(true);
nameField.set(null, Boolean.FALSE);
} catch (Exception e) {
log.error(e.getMessage(),e);
}
}
}
5) 单例客户端 调用频繁可以使用资源池构建
public class AsyncClientSingleton {
private static final StaticCredentialProvider PROVIDER = StaticCredentialProvider.create(Credential.builder()
.accessKeyId(AliyunConstant.ACCESS_KEY)
.accessKeySecret(AliyunConstant.ACCESS_SECRET)
.build());
private static final AsyncClient CLIENT = AsyncClient.builder()
.credentialsProvider(PROVIDER)
.region(AliyunConstant.REGION_ID)
.overrideConfiguration(ClientOverrideConfiguration.create().setEndpointOverride(AliyunConstant.END_POINT))
.build();
private AsyncClientSingleton() {}
public static AsyncClient getInstance() {
return CLIENT;
}
}
6)短信类型枚举
@AllArgsConstructor
@Getter
public enum MsgTempEnum {
COOPERATE_INTENTION(10, "标识码验证成功","COOPERATE_INTENTION"),
EDUCATION_TRAINING(11, "订阅成功","EDUCATION_TRAINING")
}
7) 短信工具类
@Slf4j
@Component
public class SendMsg {
@Resource
private IMessageService messageService;
private static IMessageService messageServiceInstance;
@PostConstruct
public void initInstance() {
messageServiceInstance = messageService;
}
public static SendSmsResponseBody sendSms(MsgTempEnum msgTempEnum, String phoneNumbers, Map<String, String> paramsMap) {
return sendSms(msgTempEnum, Collections.singletonList(phoneNumbers), paramsMap);
}
public static SendSmsResponseBody sendSms(MsgTempEnum msgTempEnum, List<String> numbers, Map<String, String> paramsMap) {
String code = msgTempEnum.getCode();
MsgTemp msgTemp = InitBaseData.msgTempMap.get(code);
String phoneNumbers = StringUtils.join(numbers, ",");
SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
.phoneNumbers(phoneNumbers)
.templateCode(msgTemp.getTemplateCode())
.templateParam(JSONUtil.toJsonStr(paramsMap))
.signName(CommonConstant.SIGN_NAME)
.build();
try {
CompletableFuture<SendSmsResponse> response = AsyncClientSingleton.getInstance().sendSms(sendSmsRequest);
SendSmsResponse sendSmsResponse = response.get();
if (sendSmsResponse == null) {
return null;
}
SendSmsResponseBody respBody = sendSmsResponse.getBody();
for (String number : numbers) {
Message message = new Message();
message.setMessageType("SMS");
message.setMessageCategory(code);
message.setMessageContent(MessageFormat.format(msgTemp.getTemplateDesc(), new ArrayList<>(paramsMap.values()).toArray()));
message.setTitle(msgTemp.getName());
message.setReceiver(number);
if (respBody != null) {
message.setCallMessage("SmsResult{" + "bizId='" + respBody.getBizId() + ", code='" + respBody.getCode() +
", message='" + respBody.getMessage() + ", requestId='" + respBody.getRequestId() + '}');
message.setStatus("OK".equals(respBody.getCode()) ? 1 : 0);
}
messageServiceInstance.save(message);
}
return sendSmsResponse.getStatusCode() != 200 ? null : respBody;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
}
8) 调用示例
LinkedHashMap可以保证入参顺序一致,方便后台记录短信发送日志。
public void sendNoticeMsg(String receiver, String name, String tel, MsgTempEnum msgTempEnum){
Map<String,String> map = new LinkedHashMap<>();
map.put("name",name);
map.put("tel",tel);
sendNoticeMsg(receiver,map,msgTempEnum);
}