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***********yaccessSecret: e***********************zregionId: 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;@Overridepublic 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 {@Resourceprivate IMessageService messageService;private static IMessageService messageServiceInstance;@PostConstructpublic 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);
}