阿里大于发送短信
阿里大于短信服務
demo
注冊頁面上有短信發送的按鈕,當用戶點擊發送短信,我們需要生成驗證碼,發送給用戶。我們將使用阿里提供的阿里大于來實現短信發送。
?
創建短信微服務
因為系統中不止注冊一個地方需要短信發送,因此我們將短信發送抽取為微服務:learn-sms-service,凡是需要的地方都可以使用。
另外,因為短信發送API調用時長的不確定性,為了提高程序的響應速度,短信發送我們都將采用異步發送方式,即:
-
短信服務監聽MQ消息,收到消息后發送短信。
-
其它服務要發送短信時,通過MQ通知短信微服務。
創建module
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>learn</artifactId><groupId>com.learn.parent</groupId><version>1.0.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.learn.sms</groupId><artifactId>learn-sms-service</artifactId><version>1.0.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><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.0.0</version></dependency></dependencies> </project>編寫啟動類
@SpringBootApplication public class SmsApplication {public static void main(String[] args) {SpringApplication.run(SmsApplication.class, args);} }編寫application.yml
server:port: 8086 spring:application:name: sms-servicerabbitmq:host: 192.168.56.101username: learnpassword: learnvirtual-host: /learn編寫短信工具類
項目結構:
屬性抽取
我們首先把一些常量抽取到application.yml中:
learn:sms:accessKeyId: JWffwFJIwada # 你自己的accessKeyIdaccessKeySecret: aySRliswq8fe7rF9gQyy1Izz4MQ # 你自己的AccessKeySecretsignName: 碧溪商城 # 簽名名稱verifyCodeTemplate: SMS_133976814 # 模板名稱然后注入到屬性類中:
@ConfigurationProperties(prefix = "learn.sms") public class SmsProperties {String accessKeyId;String accessKeySecret;String signName;String verifyCodeTemplate;public String getAccessKeyId() {return accessKeyId;}public void setAccessKeyId(String accessKeyId) {this.accessKeyId = accessKeyId;}public String getAccessKeySecret() {return accessKeySecret;}public void setAccessKeySecret(String accessKeySecret) {this.accessKeySecret = accessKeySecret;}public String getSignName() {return signName;}public void setSignName(String signName) {this.signName = signName;}public String getVerifyCodeTemplate() {return verifyCodeTemplate;}public void setVerifyCodeTemplate(String verifyCodeTemplate) {this.verifyCodeTemplate = verifyCodeTemplate;} }工具類
我們把阿里提供的demo進行簡化和抽取,封裝一個工具類:
@Component @EnableConfigurationProperties(SmsProperties.class) public class SmsUtils {@Autowiredprivate SmsProperties prop;//產品名稱:云通信短信API產品,開發者無需替換static final String product = "Dysmsapi";//產品域名,開發者無需替換static final String domain = "dysmsapi.aliyuncs.com";static final Logger logger = LoggerFactory.getLogger(SmsUtils.class);public SendSmsResponse sendSms(String phone, String code, String signName, String template) throws ClientException {//可自助調整超時時間System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");//初始化acsClient,暫不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou",prop.getAccessKeyId(), prop.getAccessKeySecret());DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);//組裝請求對象-具體描述見控制臺-文檔部分內容SendSmsRequest request = new SendSmsRequest();request.setMethod(MethodType.POST);//必填:待發送手機號request.setPhoneNumbers(phone);//必填:短信簽名-可在短信控制臺中找到request.setSignName(signName);//必填:短信模板-可在短信控制臺中找到request.setTemplateCode(template);//可選:模板中的變量替換JSON串,如模板內容為"親愛的${name},您的驗證碼為${code}"時,此處的值為request.setTemplateParam("{\"code\":\"" + code + "\"}");//選填-上行短信擴展碼(無特殊需求用戶請忽略此字段)//request.setSmsUpExtendCode("90997");//可選:outId為提供給業務方擴展字段,最終在短信回執消息中將此值帶回給調用者request.setOutId("123456");//hint 此處可能會拋出異常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);logger.info("發送短信狀態:{}", sendSmsResponse.getCode());logger.info("發送短信消息:{}", sendSmsResponse.getMessage());return sendSmsResponse;} }編寫消息監聽器
接下來,編寫消息監聽器,當接收到消息后,我們發送短信。
@Component @EnableConfigurationProperties(SmsProperties.class) public class SmsListener {@Autowiredprivate SmsUtils smsUtils;@Autowiredprivate SmsProperties prop;@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "learn.sms.queue", durable = "true"),exchange = @Exchange(value = "learn.sms.exchange", ignoreDeclarationExceptions = "true"),key = {"sms.verify.code"}))public void listenSms(Map<String, String> msg) throws Exception {if (msg == null || msg.size() <= 0) {// 放棄處理return;}String phone = msg.get("phone");String code = msg.get("code");if (StringUtils.isBlank(phone) || StringUtils.isBlank(code)) {// 放棄處理return;}// 發送消息SendSmsResponse resp = this.smsUtils.sendSms(phone, code, prop.getSignName(),prop.getVerifyCodeTemplate());} }我們注意到,消息體是一個Map,里面有兩個屬性:
-
phone:電話號碼
-
code:短信驗證碼
?
?
總結
- 上一篇: 数据是否可用校验
- 下一篇: redis的安装及springDataR