SpringBoot整合阿里云短信服务实现方案
一、阿里云短信服务准备工作
1. 开通阿里云短信服务
- 注册/登录阿里云账号(可使用支付宝/淘宝账号直接登录)
- 在阿里云首页搜索"短信服务"并进入控制台
- 点击"免费开通"按钮启用短信服务
- 如有需要,根据提示补充个人/公司资质信息
2. 获取必要的配置信息
- 短信签名(SignName):短信发送时显示的发送者名称,需在控制台申请
- 短信模板(TemplateCode):定义短信内容的固定部分和可替换参数,需在控制台申请
- AccessKey凭证:在阿里云控制台的"AccessKey管理"中创建和获取
二、SpringBoot项目整合
1. 添加Maven依赖
在pom.xml文件中添加以下依赖:
<!-- 阿里云核心SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.3</version>
</dependency>
<!-- 阿里云短信服务SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.2.1</version>
</dependency>
<!-- HTTP客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
2. 配置文件设置
在application.properties或application.yml中添加配置:
application.properties方式:
# 阿里云访问凭证
spring.aliyun.access-key=your-access-key
spring.aliyun.secret-key=your-secret-key
# 阿里云短信服务配置
spring.aliyun.sms.sign-name=your-sign-name
spring.aliyun.sms.template-code=your-template-code
application.yml方式:
spring:
aliyun:
access-key: your-access-key
secret-key: your-secret-key
sms:
sign-name: your-sign-name
template-code: your-template-code
3. 编写短信服务实现类
创建AliyunSmsService.java:
package com.example.service;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class AliyunSmsService {
@Value("${spring.aliyun.access-key}")
private String accessKey;
@Value("${spring.aliyun.secret-key}")
private String secretKey;
@Value("${spring.aliyun.sms.sign-name}")
private String signName;
@Value("${spring.aliyun.sms.template-code}")
private String templateCode;
/**
* 发送短信
* @param phoneNumbers 手机号码
* @param templateParam 短信模板参数
* @return 发送结果
*/
public boolean sendSms(String phoneNumbers, String templateParam) {
// 手机号格式验证
if (!validatePhone(phoneNumbers)) {
return false;
}
try {
// 初始化DefaultProfile
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKey, secretKey);
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", "cn-hangzhou");
request.putQueryParameter("PhoneNumbers", phoneNumbers);
request.putQueryParameter("SignName", signName);
request.putQueryParameter("TemplateCode", templateCode);
request.putQueryParameter("TemplateParam", templateParam);
// 发送请求
CommonResponse response = client.getCommonResponse(request);
// 解析响应结果
String responseData = response.getData();
return responseData.contains("\"Code\":\"OK\"");
} catch (ClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 验证手机号格式
* @param phone 手机号
* @return 是否有效
*/
private boolean validatePhone(String phone) {
String regex = "^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$";
return phone.matches(regex);
}
}
4. 编写Controller层接口
创建SmsController.java:
package com.example.controller;
import com.example.service.AliyunSmsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/sms")
public class SmsController {
@Autowired
private AliyunSmsService aliyunSmsService;
/**
* 发送验证码短信
* @param phone 手机号
* @return 发送结果
*/
@GetMapping("/sendCode/{phone}")
public String sendVerificationCode(@PathVariable String phone) {
// 生成随机验证码
String code = generateRandomCode(6);
// 构建模板参数JSON
String templateParam = "{\"code\":\"" + code + "\"}";
// 发送短信
boolean result = aliyunSmsService.sendSms(phone, templateParam);
if (result) {
// 实际项目中这里需要将验证码存入缓存(Redis等),设置过期时间
return "短信发送成功,验证码:" + code;
} else {
return "短信发送失败";
}
}
/**
* 生成指定长度的随机数字验证码
* @param length 验证码长度
* @return 验证码
*/
private String generateRandomCode(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append((int)(Math.random() * 10));
}
return sb.toString();
}
}
三、高级功能扩展
1. 验证码缓存管理
建议使用Redis存储验证码,设置合理的过期时间:
@Service
public class SmsVerificationService {
@Autowired
private StringRedisTemplate redisTemplate;
private static final long EXPIRE_TIME = 5 * 60; // 5分钟
public void storeVerificationCode(String phone, String code) {
redisTemplate.opsForValue().set("sms:code:" + phone, code, EXPIRE_TIME, TimeUnit.SECONDS);
}
public boolean verifyCode(String phone, String code) {
String storedCode = redisTemplate.opsForValue().get("sms:code:" + phone);
return code != null && code.equals(storedCode);
}
}
2. 发送频率限制
防止恶意刷短信:
public boolean checkSendFrequency(String phone) {
String key = "sms:limit:" + phone;
Long count = redisTemplate.opsForValue().increment(key);
if (count == 1) {
redisTemplate.expire(key, 1, TimeUnit.HOURS); // 1小时内的限制
}
return count <= 5; // 每小时最多发送5条
}
四、使用注意事项
-
安全性考虑:
- 避免在代码中硬编码AccessKey和SecretKey
- 定期更换AccessKey
- 开启短信服务的IP白名单
-
错误处理:
- 完善异常捕获和日志记录
- 实现重试机制处理临时网络问题
-
测试建议:
- 先使用阿里云控制台的"快速学习和测试"功能验证短信服务配置正确
- 项目测试时,先使用测试手机号
五、完整流程测试
- 启动SpringBoot应用
- 访问
http://localhost:8080/api/sms/sendCode/13800138000发送短信 - 检查手机号是否收到短信
- 验证功能和错误处理是否正常工作
通过以上步骤,您可以成功实现SpringBoot与阿里云短信服务的整合,实现短信发送功能。