目录
一、前期准备工作
1. 注册登录阿里云
2. 氪金(充值)
停停停,别不看这文章,你不氪金就不能用阿里云的短信服务,所以Folow me,点击首页右上角的头像,然后在弹出框中点击充值,充值多少您随意,开始氪金吧!
3. 获取AccessKey
注意:这些配置都是为了连接阿里云短信服务做准备,别怀疑我,跟着我
在首页上点击控制台
:
把鼠标放在右上角头像
上,不用点击,然后在下拉框中点击AccessKey管理
:
选择弹出框中的“开始使用字用户AccessKey
”,如果你选择“继续使用AccessKey”,使用这种方式生成的AccessKey将会拥有你的账户完全的权限,也就是不会受到限制,当这个AccessKey泄露之后,你需要把所有使用到这个AccessKey的地方都变成新的AccessKey,这就很麻烦,而如果你选择“开始使用字用户AccessKey”,里面可以设置用户组和单个用户,你可以把权限分配在不同用户组中,单个用户继承用户组的权限,当AccessKey泄露的时候,你只需要更改具有该权限的用户中的AccessKey就可以了,这样在权限控制方面更完善
点击侧边栏的用户组
,然后在右边点击创建用户组
,填写相关信息,点击确定后如果需要输入手机验证码,那就按要求操作:
用户组创建完成:
在创建的用户组右边点击添加权限:
在右边的弹出框中输入相关信息,除了我标注在下图上的,其他信息都不用改变:
这就完成了用户组的授权,然后点击侧变栏中的用户
,随后在右侧屏幕中点击创建用户
:
填写创建用户的相关信息:
将用户添加到用户组:
这就完成了创建用户并把用户添加到用户组的过程,接下来我们来获取AccessKey:
点击上面的用户登录名称/显示名称
之后,在右侧出现的页面中往下滑,点击创建AccessKey
,如果让你输入手机验证码,按照要求操作即可:
下载CSV文件,如果你不下载,关闭窗口之后密码就无法查看了:
以上就完成了AccessKey的获取
4. 配置模板和签名
注意:对于含有验证码的短信,我给出一个例子分析一下哪个是签名,哪个是模板,例子如下:
【阿里云】尊敬的用户:您的校验码:883458,工作人员不会索取,请勿泄漏。
上述例子中【】中的阿里云就是签名名称,而尊敬的用户:您的校验码:883458,工作人员不会索取,请勿泄漏。
就是模板,其中883458是验证码,在模板中会被{code}代替
接下来在控制台首页中搜索短信服务
,点击下拉框中出现的控制台入口
中的短信服务
:
点击国内消息,点击右侧的添加签名,签名中填写的内容就是我们上面所说的签名名称,例如上述短信中的阿里云,所以不能随意填写,不然签名无法通过就很麻烦:
还是在国内短信
上,选择右侧页面文本短信
下面的模板管理
,点击添加模板:
然后你就需要等待了,估计审核要半小时吧
友情提示:如果有阿里的客户经理给你打电话(电话号码:95187;名称:阿里云计算有限公司),他们是让你以后有阿里云服务上有啥问题直接和他们联系,如果你有需要就加上他的钉钉,如果你是个人用户,没有什么需要就直接告诉他你在忙没时间挂了就好,它们和上述的审核没关系,我填写了审核资料之后他们就打过来了,我还以为是他们是审核我模板和签名的呢,哈哈哈!
5. 获取测试代码
点击短信服务控制台侧边栏最下方的帮助文档:
找到SendSms页面:
在右边页面中往下滑动,找到调试,然后点击调试:
输入相关参数信息,点击发起调用:
如果不出意外的话,你就可以收到短信了,没收到的肯定是哪步漏了(氪金了吗???),仔细检查一下
复制示例代码的内容:
不要关闭上述页面,毕竟示例代码我们等会要用
二、springboot+redis+阿里云短信服务
1. 创建一个springboot项目
如果你想把该项目放在新的工程里面你还要新建一个工程,之后在该工程中新建springboot项目,这个我就不仔细说了,需要注意的是在选择依赖的时候需要选择Web-》Spring Web和NoSQL-》Spring Data Redis(Access+Driver)
2. 解读项目结构
项目结构如下:
对以上项目结构进行解读,controller层接收请求,使用的是RestFull风格,我们在上面复制的示例代码写在Service层的实现类中,工具类BaseUtil用来提供验证码,配置文件application.properties中只配置了端口号和redis的配置信息,我连接的的是本地的redis,虽然默认配置的就是本地的,我配置出来的目的是让你在连接Linux版本的redis时好用,pom.xml中有redis依赖、fastjson依赖、springboot web依赖等,接下来我将会把全部文件中的代码贴出来
3. 全部代码
SendSmsController.java:
@RestController
public class SendSmsController {
@Resource
private SendSmsService sendSmsService;
@Resource
private RedisTemplate<String, String> redisTemplate;
/**
* 给用户发送验证码
* @param phone 手机号
* @return
*/
@RequestMapping("/send/{phone}")
public String send(@PathVariable("phone") String phone) {
// 存储返回结果
Map<String, Object> result = new HashMap<>();
// 获取该手机用户在redis中的验证码
String code = redisTemplate.opsForValue().get(phone);
// 如果redis里面没有该用户的验证码,说明该用户的验证码未生成或者过期了,可以生成新的验证码
if (StringUtils.isEmpty(code)) {
// 使用工具类生成四位的数字验证码
code = BaseUtil.getRandomCode(4);
// 将redisTemplate模板对象的key的序列化方式修改为new StringRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 将phone当做key,将code当做value存进redis中,时间为5分钟
redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES);
// 获取信息发送成功与否的标志
boolean flag = sendSmsService.send(phone, code);
// 根据信息是否发送成功,返回不同的内容
if (flag){
result.put("message", "验证码发送成功");
} else {
result.put("message", "验证码发送失败");
}
} else {
// redis中有该用户的验证码,就不在重新生成了
result.put("message", "验证码有效时间为5分钟");
}
// 向前端返回信息
return JSONObject.toJSONString(result);
}
}
SendSmsService接口:
public interface SendSmsService {
boolean send(String phone, String code);
}
SendSmsServiceImpl.java:
@Service
public class SendSmsServiceImpl implements SendSmsService {
/**
* 向阿里云短信服务发送请求
* @param phone 电话号码
* @param code 验证码
* @return 是否发送成功
*/
@Override
public boolean send(String phone, String code) {
// 连接阿里云
// *********注意:AccessKey ID 和 AccessKey Secret 需要改成你自己的**********
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", AccessKey ID, AccessKey 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");
// 生成装有短信验证码的map
Map<String,Object> messageMap = new HashMap<>();
messageMap.put("code", code);
// 填写请求参数
request.putQueryParameter("PhoneNumbers", phone); // 电话
// *********注意:签名名称 需要改成你自己的**********
request.putQueryParameter("SignName", 签名名称); // 签名名称
// *********注意:模板CODE 需要改成你自己的**********
request.putQueryParameter("TemplateCode", 模板CODE); // 模版CODE
request.putQueryParameter("TemplateParam", JSONObject.toJSONString(messageMap)); // 短信模板变量对应的实际值
try {
// 发送请求并接受返回值
CommonResponse response = client.getCommonResponse(request);
// 把json格式字符串变成Json对象
JSONObject jsonObject = JSON.parseObject(response.getData());
// 请求状态码,返回OK代表请求成功,来自官方文档
String resCode = jsonObject.getString("Code");
return "OK".equals(resCode);
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
return false;
}
}
以上代码改写自示例代码,需要注意的是:
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", AccessKey ID, AccessKey Secret);
中的AccessKey ID 和 AccessKey Secret就是我让你们保存的CSV文件,文件名是AccessKey.csv
,如果你找不到的话,那就先到控制台,然后把鼠标放在右上角的头像上,在下拉框中选择AccessKey管理
,点击开始使用子用户AccessKey
,在左侧边栏中选择用户
,在左侧页面中点击用户登录名称/显示名称
下面的用户名称,之后把页面滑到最下方,点击创建AccessKey,按照要求输入验证码,之后把生成的AccessKey ID 和 AccessKey Secret填到代码中,同一个用户只能生成两个AccessKey,所以你如果已经两个了,那就删除一个,在重新创建:
继续介绍参数:
request.putQueryParameter("PhoneNumbers", phone);
电话来自于前端,可不是我们自己的号码
request.putQueryParameter("SignName", 签名名称);
例如我填写的ABC商城
,看看你的示例代码,里面有你自己的签名名称,如果找不到就去短信服务控制台–》国内消息–》签名管理–》签名名称下复制
request.putQueryParameter("TemplateCode", 模板CODE);
例如我填写的SMS_20*******
,看看你的示例代码,里面有你自己的模板CODE,如果找不到就去短信服务控制台–》国内消息–》模板管理–》模板OCDE下复制
request.putQueryParameter("TemplateParam", JSONObject.toJSONString(messageMap));
由于官方要求的样式是例如{“code”: “1111”}这种的json格式字符串,所以我使用messageMap来装载code,如下:
Map<String,Object> messageMap = new HashMap<>();
messageMap.put("code", code);
之后使用fastJson中的JSONObject.toJSONString()
方法把map变成了json格式字符串
所有的参数都已经配置完成了,然后说一下返回值,通过response.getData()
获得的就是json格式的字符串,如下:
{
"Message":"OK",
"RequestId":"2184201F-BFB3-446B-B1F2-C746B7BF0657",
"BizId":"197703245997295588^0",
"Code":"OK"
}
所以我把这些Json格式的字符串变成了Json对象,之后从里面取出了Code
,然后让它和OK比较,因为官方说CODE是请求状态码,返回OK代表请求成功。
以上的参数信息配置和返回值都来自于官方文档,地址是:https://help.aliyun.com/document_detail/101414.html
请大家结合我的代码、示例代码、官方文档一起食用,我能力有限,可能说的有点琐碎
BaseUtil.java:
public class BaseUtil {
/**
* 生成一串随机的数字,用作短信验证码
*
* @param count
* @return
*/
public static String getRandomCode(int count) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < count; i++) {
// 这个地方不能直接使用int进行强制转换,因为int进行向零取整,那样就不会取到9了,但是也可以*10,
// 这样就可以直接使用int进行强制转换,而不是使用round进行四舍五入之后在使用int强制转换
int index = (int) Math.round(Math.random() * 9);
stringBuilder.append(index);
}
return stringBuilder.toString();
}
}
DemoApplication.java:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
application.properties:
server.port=9090
# 连接远程redis,需要把这个改成远程的ip地址
spring.redis.host=localhost
# 连接远程redis,需要把这个改成远程的redis端口号,不过远程的默认也是6379
spring.redis.port=6379
pom.xml:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.aliyun</groupId>
<artifactId>demo</artifactId>
<version>1.0.0</version>
<name>demo</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--springboot web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot的测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--阿里云Java SDK核心库-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.3</version>
</dependency>
<!--阿里巴巴的fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!--使用redis缓存短信验证码-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4. 测试
运行启动类,在浏览器地址栏输入http://localhost:9090/send/184******07
,点击回车如果返回的是{"message", "验证码发送成功"}
,那说明你就成功了,如下所示:
如果你用的是你自己的手机号码测试的,那你肯定会收到一个验证码,例如: