java 阿里云接口实现发送短信验证码

  • 1. 阿里云后台配置短信相关
    • 1.1 开通短信服务
    • 1.2 添加模板签名
    • 1.3 创建秘钥
    • 1.4 短信需要后台授权--注意点
  • 2 java--简单实现短信验证码发送
    • 2.1 引入pom依赖
    • 2.2 application.yml配置阿里AK
    • 2.3 编写阿里配置文件实体类
    • 2.4 编写阿里工具类
    • 2.5 编写短信缓存
    • 2.6 编写发送短信随机码--6位数
    • 2.7 发送短信接口
    • 2.8 校验验证码有没有过期
    • 2.9 判断手机号是否为空,手机格式是否有误
    • 2.10 验证成功后,移除缓存中的手机号验证码
  • 3 修改短信接口
    • 3.1 添加短信类型
    • 3.2 获取配置文件中短信时间跟最大次数
    • 3.3 对特别类型下进行校验
    • 3.4 动态设置失效时间
    • 3.5 规定时间内没有失效的校验
    • 3.6新建表,保存短信日志,
    • 3.8 结果图
  • 4 注意点
    • 4.1 模板签名正确性
    • 4.2 授权问题
    • 4.3 尽量把次数,失效时间,AK写到配置文件,方便修改
    • 4.4 谢谢点赞 ~^o^~

前言–很久没更新过东西了,突然想起来短信,回顾了一下之前的小项目,把阿里短信的内容简要讲述一下.

1. 阿里云后台配置短信相关

1.1 开通短信服务

打开官网,直接搜索短信服务,点击短信控制台进入开通短信服务。
阿里短信服务:https://www.aliyun.com/product/sms

1.2 添加模板签名

开通之后,配置模板及签名,可根据自己需求配置,审核时间官方给得:
一般模板预计2小时内审核完成,审核通过后可使用。工作时间:9:00-23:00 (法定节日顺延),建议您尽量在18:00前提交申请。

1.3 创建秘钥

AccessKey ID:***************
AccessKey Secret:**********
(建议保存好,很关键得一个AK,具有该账户完全的权限)

1.4 短信需要后台授权–注意点

(之前遇到得一个问题)没授权报错,发送失败

2 java–简单实现短信验证码发送

2.1 引入pom依赖

阿里短信服务文档、sdk下载https://help.aliyun.com/product/44282.html如果不是maven项目直接下载两个jar导入。
以下是maven

<!-- 阿里云短信 -->
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.1.0</version>
</dependency>
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>1.1.0</version>
</dependency>

2.2 application.yml配置阿里AK

ali:#阿里AK 换成自己的accessKeyId: ************************accessKeySecret: *******************#短信每天发送最大次数sendMaxTime: 10#短信失效时间 例如2分钟= 60*1000*2 =120000codeFailureTime: 120000

2.3 编写阿里配置文件实体类

package com.jzyb.common.utils.wx;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "ali")
public class AliConfig {/** accessKeyId */private static String accessKeyId;/** accessKeySecret */private static String accessKeySecret;/** 短信每天发送最大次数 */private static Integer sendMaxTime;/** 短信失效时间 */private static Long codeFailureTime;public static Integer getSendMaxTime() {return sendMaxTime;}public void setSendMaxTime(Integer sendMaxTime) {AliConfig.sendMaxTime = sendMaxTime;}public static Long getCodeFailureTime() {return codeFailureTime;}public void setCodeFailureTime(Long codeFailureTime) {AliConfig.codeFailureTime = codeFailureTime;}public static String getAccessKeyId() {return accessKeyId;}public void setAccessKeyId(String accessKeyId) {AliConfig.accessKeyId = accessKeyId;}public static String getAccessKeySecret() {return accessKeySecret;}public void setAccessKeySecret(String accessKeySecret) {AliConfig.accessKeySecret = accessKeySecret;}}

2.4 编写阿里工具类

package com.jzyb.common.utils.wx;import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;public class AliyunSmsUtil {// 产品名称:云通信短信API产品,开发者无需替换static final String product = "Dysmsapi";// 产品域名,开发者无需替换static final String domain = "dysmsapi.aliyuncs.com";static final String accessKeyId = AliConfig.getAccessKeyId();static final String accessKeySecret = AliConfig.getAccessKeySecret();public static SendSmsResponse sendCode(String mobile, String code) throws ClientException {// 可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");// 初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);// 组装请求对象-具体描述见控制台-文档部分内容SendSmsRequest request = new SendSmsRequest();// 必填:待发送手机号request.setPhoneNumbers(mobile);// 必填:短信签名-可在短信控制台中找到// request.setSignName("兰考县人力资源和社会保障");request.setSignName("巩义人社");// 必填:短信模板-可在短信控制台中找到request.setTemplateCode("SMS_154500049");// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为request.setTemplateParam("{\"code\":\"" + code + "\"}");// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)// request.setSmsUpExtendCode("90997");// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者request.setOutId("yourOutId");// hint 此处可能会抛出异常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);return sendSmsResponse;}public static SendSmsResponse sendCode(String signName, String templateCode, String mobile, String code)throws ClientException {// 可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");// 初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);// 组装请求对象-具体描述见控制台-文档部分内容SendSmsRequest request = new SendSmsRequest();// 必填:待发送手机号request.setPhoneNumbers(mobile);// 必填:短信签名-可在短信控制台中找到request.setSignName(signName);// 必填:短信模板-可在短信控制台中找到request.setTemplateCode(templateCode);// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为request.setTemplateParam("{\"code\":\"" + code + "\"}");// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)// request.setSmsUpExtendCode("90997");// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者request.setOutId("yourOutId");// hint 此处可能会抛出异常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);return sendSmsResponse;}public static int getCode() {return (int) ((Math.random() * 9 + 1) * 100000);}public static void main(String[] args) {try {sendCode("模板名", "SMS_*********", "手机号", getCode() + "");} catch (ClientException e) {e.printStackTrace();}}
}

2.5 编写短信缓存

package com.jzyb.common.utils.wx;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;public class Cache {// 键值对集合private final static Map<String, Entity> map = new HashMap<>();// 定时器线程池,用于清除过期缓存private final static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();/*** 添加缓存** @param key*            键* @param data*            值*/public synchronized static void put(String key, Object data) {Cache.put(key, data, 0);}/*** 添加缓存** @param key*            键* @param data*            值* @param expire*            过期时间,单位:毫秒, 0表示无限长*/public synchronized static void put(final String key, Object data, long expire) {// 清除原键值对Cache.remove(key);// 设置过期时间if (expire > 0) {Future future = executor.schedule(new Runnable() {@Overridepublic void run() {// 过期后清除该键值对synchronized (Cache.class) {map.remove(key);}}}, expire, TimeUnit.MILLISECONDS);map.put(key, new Entity(data, future));} else {// 不设置过期时间map.put(key, new Entity(data, null));}}/*** 读取缓存** @param key*            键* @return*/public synchronized static Object get(String key) {Entity entity = map.get(key);return entity == null ? null : entity.getValue();}/*** 读取缓存** @param key*            键 * @param clazz 值类型* @return*/public synchronized static <T> T get(String key, Class<T> clazz) {return clazz.cast(Cache.get(key));}/*** 清除缓存** @param key* @return*/public synchronized static Object remove(String key) {// 清除原缓存数据Entity entity = map.remove(key);if (entity == null)return null;// 清除原键值对定时器Future future = entity.getFuture();if (future != null)future.cancel(true);return entity.getValue();}/*** 查询当前缓存的键值对数量** @return*/public synchronized static int size() {return map.size();}/*** 缓存实体类*/private static class Entity {// 键值对的valueprivate Object value;// 定时器Futureprivate Future future;public Entity(Object value, Future future) {this.value = value;this.future = future;}/*** 获取值** @return*/public Object getValue() {return value;}/*** 获取Future对象** @return*/public Future getFuture() {return future;}}
}

2.6 编写发送短信随机码–6位数

public static int getCode(){return (int)((Math.random()*9+1)*100000);
}

2.7 发送短信接口

@ApiOperation(value = "发送短信验证码", notes = "通过手机号发送短信,参数:手机号")
@ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "15858585858", required = true, paramType = "form", dataType = "String"), })
@GetMapping(value = "sendCode", produces = { "application/json;charset=UTF-8" })
public AjaxResult sendCode(String mobile) {try {String code = getCode()+"";SendSmsResponse sr=AliyunSmsUtil.sendCode("模板名", "模板id",mobile, code);if("OK".equals(sr.getCode())) {Cache.put(mobile.trim(), code, 120000);String code11 = (String) Cache.get(mobile);return AjaxResult.success("发送成功");}} catch (ClientException e) {e.printStackTrace();}return AjaxResult.error("操作失败");
}

2.8 校验验证码有没有过期

 String oldCode = (String) Cache.get(mobile);if(StringUtils.isNotEmpty(oldCode)) {return AjaxResult.warn("之前验证码还没失效");}

2.9 判断手机号是否为空,手机格式是否有误

    if(!isPhone(mobile)) {return AjaxResult.warn("手机号格式有误");}public static boolean isPhone(String phone) {String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";if (phone.length() != 11) {//MToast.showToast("手机号应为11位数");return false;} else {Pattern p = Pattern.compile(regex);Matcher m = p.matcher(phone);boolean isMatch = m.matches();//LogUtil.e(isMatch);if (!isMatch) {// MToast.showToast("请填入正确的手机号");}return isMatch;}}

2.10 验证成功后,移除缓存中的手机号验证码

Cache.remove(webUser.getMobile());

如果没啥意外,即可发送成功!

{"msg": "发送成功","code": 0
}

3 修改短信接口

3.1 添加短信类型

     @ApiOperation(value = "发送短信验证码", notes = "通过手机号发送短信,参数:手机号,type类别type 1.注册 2.修改密码 3.修改手机号 4 修改个人信息 5 忘记密码")@ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "15858585858", required = true, paramType = "form", dataType = "String"), @ApiImplicitParam(name = "type", value = "2", required = true, paramType = "form", dataType = "String"),})@GetMapping(value = "sendCode")public AjaxResult sendCode(String mobile,String type) {if(StringUtils.isNotBlank(mobile)&&StringUtils.isNotBlank(type)){//类别不为空的情况}else{//返回参数为空}

3.2 获取配置文件中短信时间跟最大次数

if(webSmsLogService.countByMobile(mobile)>AliConfig.getSendMaxTime()) {return AjaxResult.warn("当天接收验证码超限制");}

3.3 对特别类型下进行校验

/*
* 1.注册:拿注册举例,如果用户表已经有了改用户,就没有必要给这个人发送短信,因为已经注册过
* 2.忘记密码:如果用户表根本就没有这个手机号,就没有必要发忘记密码的短信--可以根据自己短信种类做判断。规避短信滥用
*/
if("1".equals(type)) {try {//判断该手机号是否已经存在--存在表示用户已经注册过,不存在的情况才能发注册的验证码if(webUserService.checkMobileSole(mobile)) {return AjaxResult.warn("手机号已经存在");}String oldCode = (String) Cache.get(mobile);if(StringUtils.isNotEmpty(oldCode)) {return AjaxResult.warn("之前验证码还没失效");}String code = getCode()+"";SendSmsResponse sr=AliyunSmsUtil.sendCode("模板名", "模板id",mobile, code);if("OK".equals(sr.getCode())) {if("OK".equals(sr.getCode())) {//发送成功将手机号 验证码 失效时间保存到Cache中Cache.put(mobile.trim(), code, AliConfig.getCodeFailureTime());return AjaxResult.success("发送成功");}} catch (ClientException e) {// TODO Auto-generated catch blocke.printStackTrace();return AjaxResult.error("调用阿里短信验证码失败");}}

3.4 动态设置失效时间

 Cache.put(mobile.trim(), code, AliConfig.getCodeFailureTime());

3.5 规定时间内没有失效的校验

 String oldCode = (String) Cache.get(mobile);if(StringUtils.isNotEmpty(oldCode)) {return AjaxResult.warn("之前验证码还没失效");}

3.6新建表,保存短信日志,

CREATE TABLE `sys_sms_log` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`phone` varchar(11) DEFAULT NULL COMMENT '手机号',`send_time` datetime DEFAULT NULL COMMENT '发送时间',`send_status` char(1) DEFAULT NULL COMMENT '发送状态:0失败;1成功',`content` varchar(100) DEFAULT NULL COMMENT '发送内容',`send_type` char(1) DEFAULT NULL COMMENT '调用方式:1.注册 2.修改密码 3.修改手机号 4 修改个人信息 5 忘记密码.',`result_code` varchar(50) DEFAULT NULL COMMENT '短信运营商的返回码',`send_bizId` varchar(50) DEFAULT NULL COMMENT '短信发送回执ID',`send_ip` varchar(20) DEFAULT NULL COMMENT '发送短信的IP地址',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='短信发送日志'

每次发送成功后将信息保存短信日志表

SendSmsResponse sr=AliyunSmsUtil.sendCode("模板名", "模板id",mobile, code);
if("OK".equals(sr.getCode())) {//发送成功将手机号 验证码 失效时间保存到Cache中Cache.put(mobile.trim(), code, AliConfig.getCodeFailureTime());String code11 = (String) Cache.get(mobile);WebSmsLog smslog = new WebSmsLog();smslog.setContent("");smslog.setPhone(mobile);smslog.setResultCode("OK");smslog.setSendBizid(sr.getRequestId());//smslog.setSendIp(sendIp);smslog.setSendStatus(1);smslog.setSendTime(DateUtils.getNowDate());smslog.setSendType(type);sysSmsLogService.insertSysSmsLog(smslog);return AjaxResult.success("发送成功");
}

3.8 结果图


发送结果

4 注意点

4.1 模板签名正确性

 AK --模板名--模板id这些都是对应的,项目多了有时候会把另外一个项目的AK拿到这个项目用,但是模板id却是这个项目的,尽量多审查几遍,保证模板设置要与控制台的短信模板相对应

4.2 授权问题

(遇到过一次)需要阿里后台点一下

4.3 尽量把次数,失效时间,AK写到配置文件,方便修改

4.4 谢谢点赞 ^o^

本人小白,以上是自己的一知半解,有任何问题请留言评论,及时改正,及时回复,互相学习互相进步。手打2小时,也希望对新手有帮助,看的开心话点赞关注。原创–转载请备明出处–叩谢!

阿里云接口实现发送短信验证码相关推荐

  1. java 阿里云接口实现发送短信验证码

    1.先去阿里云开通短信服务: 2.添加模板及签名:需要审核,个人账户审核就几分钟就OK 先解释一下模板及签名: 标准参照:https://help.aliyun.com/document_detail ...

  2. php实现短信找回密码,thinkphp5怎么调用云片接口实现发送短信验证码找回密码功能...

    thinkphp5怎么调用云片接口实现发送短信验证码找回密码功能 发布时间:2020-12-11 12:33:42 来源:亿速云 阅读:60 作者:小新 小编给大家分享一下thinkphp5怎么调用云 ...

  3. html5实现短信验证修改密码,thinkphp5如何调用云片接口实现发送短信验证码找回密码功能...

    下面由thinkphp框架教程栏目给大家介绍thinkphp5如何调用云片接口实现发送短信验证码找回密码功能,希望对需要的朋友有所帮助! 思路: 1.用户输入手机号,请求获取短信验证码. 2.thin ...

  4. 使用容联云Celery异步发送短信验证码

    文章目录 Celery/容联云 安装与命令 安装 celery启动命令 一.Celery 1.配置Celery 2.创建任务文件 二.容联云 1. 配置容联云 settings.py 2. 使用Sms ...

  5. 阿里云——Java实现手机短信验证码功能

    目录 如何实现短信验证码功能 1.准备工作 1.1 注册 阿里云 账号,并完成实名认证.找到短信服务功能. 1.2 开通短信服务 1.3 签名与模板 1.4 获取AccessKey 1.5 打开短信控 ...

  6. 基于MFC与阿里云制作简易发送短信

    ***~~ 做到最后可能会只是不能识别汉字,但是能识别英文和数字,有待改进的地方` ` ~~ *** # 详细步骤见如下 一. 新建一个MFC项目:打开VS2013,文件->新建->项目 ...

  7. 阿里云API定时发送短信(小记)

    定时任务的代码:import com.google.gson.Gson; import com.jianke.bid.common.SMSUtils; import org.springframewo ...

  8. 阿里云服务 - Java实现短信验证码发送 --(完整教程)

    我们在实现登录注册的时候,常常用到了短信验证码校验,下面给大家简单介绍阿里云的短信服务平台. 相关jar包: aliyun-java-sdk-core-3.2.2.jar(点此下载) aliyun-j ...

  9. 使用阿里云短信通知服务发送短信--工具类

    public class AliyunUtils {public static boolean sendSMS(String mobilephone,Integer status) throws Se ...

最新文章

  1. R语言R原生及可视化包ggplot2绘制并排的箱图实战(Side-by-Side Boxplots)
  2. win7 设置自动关机
  3. TACACS 协议简介与开发总结
  4. 奇绩创坛 2021年秋季创业营 反馈:再接再厉
  5. Python于*args 和**kwargs使用
  6. 关于眼界、眼光、眼前的哪些....
  7. Java的引用类型(附图说明)
  8. LeetCode中二叉树相关题
  9. Django(part37)--session
  10. linux nfs 无法写入,无法写入挂载点(nfs-server),获得“权限被拒绝”
  11. 论文浅尝 | 基于平行新闻的Bootstrapping关系抽取
  12. sqlmap源码阅读_setPreprocessFunctions和_setPostprocessFunctions
  13. 分页查询为什么会报数组越界错误_Java Note-数据结构(1)数组
  14. 查询今天、昨天、本周、上周、本月、上月数据
  15. 【雷达通信】基于matlab雷达数字信号处理【含Matlab源码 281期】
  16. 修改Linux里的hosts文件
  17. Mac手动关闭暗黑模式
  18. 实现页面的图文混排布局(Web作业)
  19. list数组遍历时能不能使用remove()方法,要注意什么
  20. Metal 框架之渲染到多个视口

热门文章

  1. 《大数据》“数据立法”专题征文(截止日期:2023年6月30日)
  2. 美女福利图片API接口,免费好用
  3. 路由器的访问控制ACL
  4. 9. nio实现一个多人聊天室
  5. java如何保证类不被回收_Java垃圾回收机制
  6. 配置nginx使其支持pathinfo路径模式
  7. Django对接支付宝实现支付宝充值金币功能
  8. 「国家战略科学家」身份!AI学者朱松纯加盟清华筹建通用AI研究院
  9. Google Earth Engine(GEE)——Landsat 7条带色差修补
  10. php 企业建站系统,QCMS PHP轻量级企业建站系统 v5.0.2