update: 提交所有修改和新增功能代码
This commit is contained in:
712
阿里云SMS接口集成文档.md
Normal file
712
阿里云SMS接口集成文档.md
Normal file
@@ -0,0 +1,712 @@
|
||||
# 阿里云SMS短信服务集成文档
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [Maven依赖](#maven依赖)
|
||||
3. [配置文件](#配置文件)
|
||||
4. [代码实现](#代码实现)
|
||||
5. [使用示例](#使用示例)
|
||||
6. [常见问题](#常见问题)
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
本文档提供阿里云短信服务(SMS)的完整集成方案,包括验证码发送、验证码校验、发送频率限制等功能。
|
||||
|
||||
### 功能特性
|
||||
- ✅ 发送6位数字验证码
|
||||
- ✅ 验证码5分钟有效期
|
||||
- ✅ 每个手机号每天最多发送10次
|
||||
- ✅ 使用Redis存储验证码和发送次数
|
||||
- ✅ 完整的错误处理和日志记录
|
||||
|
||||
---
|
||||
|
||||
## Maven依赖
|
||||
|
||||
### pom.xml
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<!-- 阿里云短信SDK -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
<version>2.0.24</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云核心SDK -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>tea-openapi</artifactId>
|
||||
<version>0.2.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云Tea工具 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>tea-util</artifactId>
|
||||
<version>0.2.21</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置文件
|
||||
|
||||
### application.yml
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
database: 0
|
||||
password: # 如果有密码则填写
|
||||
|
||||
# 阿里云短信服务配置
|
||||
aliyun:
|
||||
sms:
|
||||
# 短信签名(需要在阿里云控制台申请)
|
||||
sign-name: 你的短信签名
|
||||
# 短信模板CODE(需要在阿里云控制台申请)
|
||||
template-code: SMS_xxxxxxxx
|
||||
# 阿里云AccessKey ID
|
||||
access-key-id: ${ALIYUN_ACCESS_KEY_ID:your-access-key-id}
|
||||
# 阿里云AccessKey Secret
|
||||
access-key-secret: ${ALIYUN_ACCESS_KEY_SECRET:your-access-key-secret}
|
||||
```
|
||||
|
||||
### 环境变量配置(推荐)
|
||||
|
||||
**Linux/Mac**:
|
||||
```bash
|
||||
export ALIYUN_ACCESS_KEY_ID=your-access-key-id
|
||||
export ALIYUN_ACCESS_KEY_SECRET=your-access-key-secret
|
||||
```
|
||||
|
||||
**Windows**:
|
||||
```cmd
|
||||
set ALIYUN_ACCESS_KEY_ID=your-access-key-id
|
||||
set ALIYUN_ACCESS_KEY_SECRET=your-access-key-secret
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 代码实现
|
||||
|
||||
### 1. Service接口
|
||||
|
||||
**SmsService.java**
|
||||
|
||||
```java
|
||||
package com.example.service;
|
||||
|
||||
/**
|
||||
* 短信服务接口
|
||||
*/
|
||||
public interface SmsService {
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*
|
||||
* @param phoneNumber 手机号码
|
||||
* @return 是否发送成功
|
||||
* @throws Exception 发送异常
|
||||
*/
|
||||
boolean sendVerificationCode(String phoneNumber) throws Exception;
|
||||
|
||||
/**
|
||||
* 验证短信验证码
|
||||
*
|
||||
* @param phoneNumber 手机号码
|
||||
* @param code 验证码
|
||||
* @return 是否验证通过
|
||||
*/
|
||||
boolean verifyCode(String phoneNumber, String code);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Service实现类
|
||||
|
||||
**SmsServiceImpl.java**
|
||||
|
||||
```java
|
||||
package com.example.service.impl;
|
||||
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.example.service.SmsService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 阿里云短信服务实现类
|
||||
*/
|
||||
@Service
|
||||
public class SmsServiceImpl implements SmsService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);
|
||||
|
||||
@Value("${aliyun.sms.sign-name}")
|
||||
private String signName;
|
||||
|
||||
@Value("${aliyun.sms.template-code}")
|
||||
private String templateCode;
|
||||
|
||||
@Value("${aliyun.sms.access-key-id}")
|
||||
private String accessKeyId;
|
||||
|
||||
@Value("${aliyun.sms.access-key-secret}")
|
||||
private String accessKeySecret;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
// 短信验证码Redis前缀
|
||||
private static final String SMS_CODE_PREFIX = "sms:code:";
|
||||
// 短信发送次数Redis前缀
|
||||
private static final String SMS_COUNT_PREFIX = "sms:count:";
|
||||
// 短信验证码有效期(分钟)
|
||||
private static final long SMS_CODE_EXPIRE = 5;
|
||||
// 每天最大发送次数
|
||||
private static final int MAX_SMS_COUNT_PER_DAY = 10;
|
||||
|
||||
/**
|
||||
* 创建阿里云短信客户端
|
||||
*/
|
||||
private Client createSmsClient() throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.accessKeyId = accessKeyId;
|
||||
config.accessKeySecret = accessKeySecret;
|
||||
config.endpoint = "dysmsapi.aliyuncs.com";
|
||||
return new Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成6位随机数字验证码
|
||||
*/
|
||||
private String generateVerificationCode() {
|
||||
Random random = new Random();
|
||||
StringBuilder code = new StringBuilder();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
code.append(random.nextInt(10));
|
||||
}
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当天结束时间的剩余秒数
|
||||
*/
|
||||
private long getSecondsUntilEndOfDay() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime endOfDay = now.toLocalDate().atTime(23, 59, 59);
|
||||
Duration duration = Duration.between(now, endOfDay);
|
||||
return duration.getSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendVerificationCode(String phoneNumber) throws Exception {
|
||||
// 1. 检查当天发送次数是否达到上限
|
||||
String countKey = SMS_COUNT_PREFIX + phoneNumber + ":" +
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
Integer count = (Integer) redisTemplate.opsForValue().get(countKey);
|
||||
|
||||
if (count != null && count >= MAX_SMS_COUNT_PER_DAY) {
|
||||
logger.warn("手机号{}今日短信发送次数已达上限: {}", phoneNumber, MAX_SMS_COUNT_PER_DAY);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 生成6位随机验证码
|
||||
String verificationCode = generateVerificationCode();
|
||||
|
||||
// 3. 构建短信请求
|
||||
Client client = createSmsClient();
|
||||
SendSmsRequest sendSmsRequest = new SendSmsRequest()
|
||||
.setSignName(signName)
|
||||
.setTemplateCode(templateCode)
|
||||
.setPhoneNumbers(phoneNumber)
|
||||
.setTemplateParam("{\"code\":\"" + verificationCode + "\"}");
|
||||
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
|
||||
try {
|
||||
// 4. 发送短信
|
||||
client.sendSmsWithOptions(sendSmsRequest, runtime);
|
||||
logger.info("短信验证码发送成功,手机号: {}", phoneNumber);
|
||||
|
||||
// 5. 将验证码保存到Redis,设置过期时间
|
||||
String codeKey = SMS_CODE_PREFIX + phoneNumber;
|
||||
redisTemplate.opsForValue().set(codeKey, verificationCode, SMS_CODE_EXPIRE, TimeUnit.MINUTES);
|
||||
|
||||
// 6. 增加当天发送次数,并设置过期时间为当天结束
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
redisTemplate.opsForValue().set(countKey, count + 1, getSecondsUntilEndOfDay(), TimeUnit.SECONDS);
|
||||
|
||||
return true;
|
||||
|
||||
} catch (TeaException error) {
|
||||
logger.error("短信发送失败, 手机号: {}, 错误信息: {}, 诊断信息: {}",
|
||||
phoneNumber, error.getMessage(), error.getData().get("Recommend"));
|
||||
return false;
|
||||
} catch (Exception error) {
|
||||
logger.error("短信发送异常, 手机号: {}", phoneNumber, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyCode(String phoneNumber, String code) {
|
||||
if (phoneNumber == null || code == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String codeKey = SMS_CODE_PREFIX + phoneNumber;
|
||||
String savedCode = (String) redisTemplate.opsForValue().get(codeKey);
|
||||
|
||||
if (savedCode != null && savedCode.equals(code)) {
|
||||
// 验证成功后删除验证码
|
||||
redisTemplate.delete(codeKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Controller控制器
|
||||
|
||||
**SmsController.java**
|
||||
|
||||
```java
|
||||
package com.example.controller;
|
||||
|
||||
import com.example.common.ApiResponse;
|
||||
import com.example.common.ResultUtils;
|
||||
import com.example.service.SmsService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 短信控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sms")
|
||||
@Tag(name = "短信接口", description = "提供短信验证码相关功能")
|
||||
public class SmsController {
|
||||
|
||||
@Autowired
|
||||
private SmsService smsService;
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*
|
||||
* @param phoneNumber 手机号
|
||||
* @return 发送结果
|
||||
*/
|
||||
@PostMapping("/sendCode")
|
||||
@Operation(summary = "发送短信验证码", description = "向指定手机号发送验证码,每个手机号每天最多发送10次")
|
||||
public ApiResponse<Boolean> sendVerificationCode(
|
||||
@Parameter(description = "手机号码", required = true)
|
||||
@RequestParam String phoneNumber) {
|
||||
try {
|
||||
boolean success = smsService.sendVerificationCode(phoneNumber);
|
||||
if (success) {
|
||||
return ResultUtils.success(true, "验证码发送成功");
|
||||
} else {
|
||||
return ResultUtils.error(40001, "发送验证码失败,请稍后重试");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return ResultUtils.error(50000, "发送验证码异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证短信验证码
|
||||
*
|
||||
* @param phoneNumber 手机号
|
||||
* @param code 验证码
|
||||
* @return 验证结果
|
||||
*/
|
||||
@PostMapping("/verifyCode")
|
||||
@Operation(summary = "验证短信验证码", description = "验证手机号和验证码是否匹配")
|
||||
public ApiResponse<Boolean> verifyCode(
|
||||
@Parameter(description = "手机号码", required = true)
|
||||
@RequestParam String phoneNumber,
|
||||
@Parameter(description = "验证码", required = true)
|
||||
@RequestParam String code) {
|
||||
boolean valid = smsService.verifyCode(phoneNumber, code);
|
||||
if (valid) {
|
||||
return ResultUtils.success(true, "验证成功");
|
||||
} else {
|
||||
return ResultUtils.error(40002, "验证码错误或已过期");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 通用响应类(可选)
|
||||
|
||||
**ApiResponse.java**
|
||||
|
||||
```java
|
||||
package com.example.common;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 通用API响应类
|
||||
*/
|
||||
@Data
|
||||
public class ApiResponse<T> {
|
||||
private int code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
public ApiResponse(int code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**ResultUtils.java**
|
||||
|
||||
```java
|
||||
package com.example.common;
|
||||
|
||||
/**
|
||||
* 响应工具类
|
||||
*/
|
||||
public class ResultUtils {
|
||||
|
||||
public static <T> ApiResponse<T> success(T data) {
|
||||
return new ApiResponse<>(200, "success", data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> success(T data, String message) {
|
||||
return new ApiResponse<>(200, message, data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> error(int code, String message) {
|
||||
return new ApiResponse<>(code, message, null);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 1. 发送验证码
|
||||
|
||||
**请求**:
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/sms/sendCode \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "phoneNumber=13800138000"
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "验证码发送成功",
|
||||
"data": true
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 验证验证码
|
||||
|
||||
**请求**:
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/sms/verifyCode \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "phoneNumber=13800138000&code=123456"
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "验证成功",
|
||||
"data": true
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 在业务代码中使用
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
@Autowired
|
||||
private SmsService smsService;
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
*/
|
||||
public void register(String phoneNumber, String code, String password) {
|
||||
// 1. 验证验证码
|
||||
if (!smsService.verifyCode(phoneNumber, code)) {
|
||||
throw new BusinessException("验证码错误或已过期");
|
||||
}
|
||||
|
||||
// 2. 执行注册逻辑
|
||||
// ...
|
||||
}
|
||||
|
||||
/**
|
||||
* 找回密码
|
||||
*/
|
||||
public void resetPassword(String phoneNumber, String code, String newPassword) {
|
||||
// 1. 验证验证码
|
||||
if (!smsService.verifyCode(phoneNumber, code)) {
|
||||
throw new BusinessException("验证码错误或已过期");
|
||||
}
|
||||
|
||||
// 2. 重置密码
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. 如何申请阿里云短信服务?
|
||||
|
||||
1. 登录[阿里云控制台](https://www.aliyun.com/)
|
||||
2. 进入"短信服务"产品页面
|
||||
3. 申请短信签名(需要企业资质或个人认证)
|
||||
4. 申请短信模板(需要审核,一般1-2个工作日)
|
||||
5. 获取AccessKey ID和AccessKey Secret
|
||||
|
||||
### 2. 短信模板格式
|
||||
|
||||
**模板示例**:
|
||||
```
|
||||
您的验证码是${code},请在5分钟内完成验证。
|
||||
```
|
||||
|
||||
**模板变量**:
|
||||
- 使用 `${变量名}` 格式
|
||||
- 代码中传递JSON格式:`{"code":"123456"}`
|
||||
|
||||
### 3. 常见错误码
|
||||
|
||||
| 错误码 | 说明 | 解决方案 |
|
||||
|--------|------|---------|
|
||||
| isv.BUSINESS_LIMIT_CONTROL | 触发业务流控 | 降低发送频率 |
|
||||
| isv.MOBILE_NUMBER_ILLEGAL | 手机号码格式错误 | 检查手机号格式 |
|
||||
| isv.TEMPLATE_MISSING_PARAMETERS | 模板参数缺失 | 检查模板参数 |
|
||||
| isv.INVALID_PARAMETERS | 参数异常 | 检查所有参数 |
|
||||
| isv.AMOUNT_NOT_ENOUGH | 账户余额不足 | 充值 |
|
||||
| isv.TEMPLATE_PARAMS_ILLEGAL | 模板变量值非法 | 检查变量值格式 |
|
||||
|
||||
### 4. 如何修改验证码位数?
|
||||
|
||||
修改 `generateVerificationCode()` 方法中的循环次数:
|
||||
|
||||
```java
|
||||
private String generateVerificationCode() {
|
||||
Random random = new Random();
|
||||
StringBuilder code = new StringBuilder();
|
||||
// 修改这里的数字,比如改为4位验证码
|
||||
for (int i = 0; i < 4; i++) {
|
||||
code.append(random.nextInt(10));
|
||||
}
|
||||
return code.toString();
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 如何修改验证码有效期?
|
||||
|
||||
修改常量 `SMS_CODE_EXPIRE`:
|
||||
|
||||
```java
|
||||
// 修改为10分钟
|
||||
private static final long SMS_CODE_EXPIRE = 10;
|
||||
```
|
||||
|
||||
### 6. 如何修改每日发送次数限制?
|
||||
|
||||
修改常量 `MAX_SMS_COUNT_PER_DAY`:
|
||||
|
||||
```java
|
||||
// 修改为5次
|
||||
private static final int MAX_SMS_COUNT_PER_DAY = 5;
|
||||
```
|
||||
|
||||
### 7. Redis连接失败怎么办?
|
||||
|
||||
确保Redis服务已启动:
|
||||
|
||||
```bash
|
||||
# Linux/Mac
|
||||
redis-server
|
||||
|
||||
# 检查Redis是否运行
|
||||
redis-cli ping
|
||||
# 应该返回 PONG
|
||||
```
|
||||
|
||||
### 8. 如何测试短信发送?
|
||||
|
||||
阿里云提供测试环境,可以使用测试手机号:
|
||||
|
||||
```java
|
||||
// 测试环境配置
|
||||
config.endpoint = "dysmsapi.aliyuncs.com"; // 正式环境
|
||||
// config.endpoint = "dysmsapi-test.aliyuncs.com"; // 测试环境(如果有)
|
||||
```
|
||||
|
||||
### 9. 生产环境安全建议
|
||||
|
||||
1. **不要硬编码密钥**:使用环境变量或配置中心
|
||||
2. **启用HTTPS**:保护API通信安全
|
||||
3. **添加图形验证码**:防止恶意刷短信
|
||||
4. **IP限流**:防止单个IP频繁请求
|
||||
5. **手机号验证**:验证手机号格式和归属地
|
||||
6. **监控告警**:设置短信发送量告警
|
||||
|
||||
### 10. 性能优化建议
|
||||
|
||||
1. **Redis连接池**:配置合理的连接池参数
|
||||
2. **异步发送**:使用 `@Async` 异步发送短信
|
||||
3. **批量发送**:如果需要群发,使用批量接口
|
||||
4. **缓存优化**:合理设置Redis过期时间
|
||||
|
||||
---
|
||||
|
||||
## 完整项目结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── main/
|
||||
│ ├── java/
|
||||
│ │ └── com/
|
||||
│ │ └── example/
|
||||
│ │ ├── controller/
|
||||
│ │ │ └── SmsController.java
|
||||
│ │ ├── service/
|
||||
│ │ │ ├── SmsService.java
|
||||
│ │ │ └── impl/
|
||||
│ │ │ └── SmsServiceImpl.java
|
||||
│ │ ├── common/
|
||||
│ │ │ ├── ApiResponse.java
|
||||
│ │ │ └── ResultUtils.java
|
||||
│ │ └── Application.java
|
||||
│ └── resources/
|
||||
│ └── application.yml
|
||||
└── test/
|
||||
└── java/
|
||||
└── com/
|
||||
└── example/
|
||||
└── service/
|
||||
└── SmsServiceTest.java
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 单元测试示例
|
||||
|
||||
**SmsServiceTest.java**
|
||||
|
||||
```java
|
||||
package com.example.service;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
class SmsServiceTest {
|
||||
|
||||
@Autowired
|
||||
private SmsService smsService;
|
||||
|
||||
@Test
|
||||
void testSendVerificationCode() throws Exception {
|
||||
// 使用测试手机号
|
||||
String phoneNumber = "13800138000";
|
||||
boolean result = smsService.sendVerificationCode(phoneNumber);
|
||||
assertTrue(result, "验证码发送应该成功");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifyCode() throws Exception {
|
||||
String phoneNumber = "13800138000";
|
||||
|
||||
// 发送验证码
|
||||
smsService.sendVerificationCode(phoneNumber);
|
||||
|
||||
// 验证错误的验证码
|
||||
boolean result1 = smsService.verifyCode(phoneNumber, "000000");
|
||||
assertFalse(result1, "错误的验证码应该验证失败");
|
||||
|
||||
// 注意:无法测试正确的验证码,因为验证码是随机生成的
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
本文档提供了阿里云SMS短信服务的完整集成方案,包括:
|
||||
|
||||
✅ Maven依赖配置
|
||||
✅ 完整的代码实现
|
||||
✅ 配置文件示例
|
||||
✅ 使用示例和测试方法
|
||||
✅ 常见问题解答
|
||||
✅ 安全和性能优化建议
|
||||
|
||||
将此文档保存到你的项目中,以后需要集成阿里云SMS时可以直接参考使用。
|
||||
|
||||
---
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [阿里云短信服务官网](https://www.aliyun.com/product/sms)
|
||||
- [阿里云短信服务API文档](https://help.aliyun.com/document_detail/101414.html)
|
||||
- [阿里云短信服务SDK](https://help.aliyun.com/document_detail/215759.html)
|
||||
- [阿里云短信服务控制台](https://dysms.console.aliyun.com/)
|
||||
Reference in New Issue
Block a user