一、准备工作
1、官方文档
阿里云短信 API 调试:API 调试
阿里云短信 API:API 文档
2、配置依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.16</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
|
3、自定义配置的提示信息
设置搜索processor
重新编译模块,之后就可以在application.yml
文件中有自定义配置的提示信息
4、配置文件
在 application.yml 配置文件中进行配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server: port: 8120
spring: profiles: active: dev application: name: service-sms
aliyun: sms: region-id: key-id: key-secret: template-code: sign-name:
|
二、工具类
1、从配置文件读取常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @Setter @Getter @Component @ConfigurationProperties(prefix = "aliyun.sms") public class SmsProperties implements InitializingBean {
private String regionId; private String keyId; private String keySecret; private String templateCode; private String signName;
public static String REGION_Id; public static String KEY_ID; public static String KEY_SECRET; public static String TEMPLATE_CODE; public static String SIGN_NAME;
@Override public void afterPropertiesSet() throws Exception { REGION_Id = regionId; KEY_ID = keyId; KEY_SECRET = keySecret; TEMPLATE_CODE = templateCode; SIGN_NAME = signName; } }
|
2、生成验证码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
public class RandomUtils {
private static final Random random = new Random();
private static final DecimalFormat fourdf = new DecimalFormat("0000");
private static final DecimalFormat sixdf = new DecimalFormat("000000");
public static String getFourBitRandom() { return fourdf.format(random.nextInt(10000)); }
public static String getSixBitRandom() { return sixdf.format(random.nextInt(1000000)); }
public static ArrayList getRandom(List list, int n) {
Random random = new Random();
HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
for (int i = 0; i < list.size(); i++) {
int number = random.nextInt(100) + 1;
hashMap.put(number, i); }
Object[] robjs = hashMap.values().toArray();
ArrayList r = new ArrayList();
for (int i = 0; i < n; i++) { r.add(list.get((int) robjs[i])); System.out.print(list.get((int) robjs[i]) + "\t"); } System.out.print("\n"); return r; } }
|
3、手机号码正则匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
public class RegexValidateUtils {
static boolean flag = false; static String regex = "";
public static boolean check(String str, String regex) { try { Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(str); flag = matcher.matches(); } catch (Exception e) { flag = false; } return flag; }
public static boolean checkEmail(String email) { String regex = "^\\w+[-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$ "; return check(email, regex); }
public static boolean checkCellphone(String cellphone) { String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,4-9]))\\d{8}$"; return check(cellphone, regex); }
public static boolean checkTelephone(String telephone) { String regex = "^(0\\d{2}-\\d{8}(-\\d{1,4})?)|(0\\d{3}-\\d{7,8}(-\\d{1,4})?)$"; return check(telephone, regex); }
public static boolean checkFax(String fax) { String regex = "^(0\\d{2}-\\d{8}(-\\d{1,4})?)|(0\\d{3}-\\d{7,8}(-\\d{1,4})?)$"; return check(fax, regex); }
public static boolean checkQQ(String QQ) { String regex = "^[1-9][0-9]{4,} $"; return check(QQ, regex); } }
|
三、实现发送短信
1、自定义断言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| @Slf4j public abstract class Assert {
public static void isTrue(boolean expression, String msg) { if (!expression) { log.info("fail..............."); } }
public static void notEquals(Object m1, Object m2, String msg) { if (m1.equals(m2)) { log.info("equals..............."); } }
public static void equals(Object m1, Object m2, String msg) { if (!m1.equals(m2)) { log.info("not equals..............."); } }
public static void notEmpty(String s, String msg) { if (StringUtils.isEmpty(s)) { log.info("is empty..............."); } } }
|
2、接口
创建 SmsService
1 2 3 4 5 6 7 8 9
| public interface SmsService {
void send(String mobile, String templateCode, Map<String,Object> param); }
|
3、实现类
创建 SmsServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| @Service @Slf4j public class SmsServiceImpl implements SmsService {
@Override public void send(String mobile, String templateCode, Map<String, Object> param) {
DefaultProfile profile = DefaultProfile.getProfile( SmsProperties.REGION_Id, SmsProperties.KEY_ID, SmsProperties.KEY_SECRET); IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest(); request.setSysMethod(MethodType.POST); request.setSysDomain("dysmsapi.aliyuncs.com"); request.setSysVersion("2017-05-25"); request.setSysAction("SendSms"); request.putQueryParameter("RegionId", SmsProperties.REGION_Id); request.putQueryParameter("PhoneNumbers", mobile); request.putQueryParameter("SignName", SmsProperties.SIGN_NAME); request.putQueryParameter("TemplateCode", templateCode);
Gson gson = new Gson(); String json = gson.toJson(param); request.putQueryParameter("TemplateParam", json);
try { CommonResponse response = client.getCommonResponse(request);
boolean success = response.getHttpResponse().isSuccess(); Assert.isTrue(success, "阿里云短信服务响应失败");
String data = response.getData(); HashMap<String, String> resultMap = gson.fromJson(data, HashMap.class); String code = resultMap.get("Code"); String message = resultMap.get("Message"); log.info("code" + code + ",message" + message);
Assert.notEquals("isv.BUSINESS_LIMIT_CONTROL", code, "短信发送过于频繁"); Assert.equals("OK", code, "短信发送失败");
} catch (ServerException e) { log.error("阿里云短信发送SDK调用失败:" + e.getErrCode() + "," + e.getErrMsg()); } catch (ClientException e) { log.error("阿里云短信发送SDK调用失败:" + e.getErrCode() + "," + e.getErrMsg()); } } }
|
3、控制层
创建类 ApiSmsController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @RestController @RequestMapping("/api/sms") @CrossOrigin @Slf4j public class ApiSmsController {
@Resource private SmsService smsService;
@GetMapping("/send/{mobile}") public String send(@PathVariable String mobile) {
Assert.notEmpty(mobile, "手机号不能为空"); Assert.isTrue(RegexValidateUtils.checkCellphone(mobile), "手机号不正确");
String code = RandomUtils.getFourBitRandom(); Map<String, Object> param = new HashMap<>(); param.put("code", code); smsService.send(mobile, SmsProperties.TEMPLATE_CODE, param);
return "短信发送成功"; } }
|
4、测试
访问端口:http://localhost:8120/api/sms/send/手机号
5、报错
期间出现了:codeisv.SMS_SIGNATURE_ILLEGAL,message 签名不合法(不存在或被拉黑)
重点检查 application.yml 配置文件,查看阿里云的配置信息,还有中文的编码格式