总结:

  • 配置好阿里云短信服务API调用所需配置项信息
  • 按业务场景自定义标识码,做到正确发送不同场景的短信验证码
  • 有一点需要特别注意:写这篇文章时,偶然发现阿里云短信服务API,在遇到以数字0开头的随机数验证码时,发送的验证码会忽略数字0,导致验证码长度不匹配。因此,建议在生成随机数验证码时,使用递归思想提前将 以数字0开头的随机数验证码过滤掉!
手动导入依赖的Jar
aliyun-java-sdk-core-3.3.1.jar aliyun-java-sdk-dysmsapi-1.0.0.jar
  • Controller
/*** @Description 阿里云短信服务 控制层* @Author blake* @Date 2018/12/6 下午5:06* @Version 1.0*/
@Api(tags = "05. 阿里云短信服务", description = "阿里云短信验证码")
@RestController
@RequestMapping("/api/common/sms")
public class AliyunSmsController extends BaseController {@Autowiredprivate AliyunSmsService aliyunSmsService;/*** 1)短信防刷 借助Redis* 2)异步接收短信发送状态,更新本地数据库的短信发送 成功与否标识位*/@ApiOperation(value = "发送短信验证码", response = Boolean.class)@PostMapping("/verification/code")public Response sendSms(@RequestBody @Valid SmsVerifyCodeRequest request)throws ClientException {return JsonSend.success(aliyunSmsService.sendSms(request));}}
  • Service
/*** @Description 阿里云短信服务 业务逻辑层* @Author blake* @Date 2018/12/6 下午5:24* @Version 1.0*/
@Service
public class AliyunSmsServiceImpl implements AliyunSmsService {private static final Logger logger = LoggerFactory.getLogger(AliyunSmsServiceImpl.class);@Autowiredprivate AliyunSmsProperties aliyunSmsProperties;@Autowiredprivate BeePlusUserAPIs beePlusUserAPIs;@Autowiredprivate RedissonClient redissonClient;@Autowiredprivate SmsSendLogDAO smsSendLogDAO;/*** @return java.lang.Boolean* @throws* @description 发送短信验证码* @params [request]*/@Overridepublic Boolean sendSms(SmsVerifyCodeRequest request)throws ClientException {String phone = request.getPhone();Boolean isCheckBusiness = request.getIsCheckBusiness();if (Objects.nonNull(isCheckBusiness) && isCheckBusiness) {// 调用Bee+方API,判断是否为会员身份,若不是会员,则提示"手机号码不存在,请移步前台办理会员!";若为会员,// 业务逻辑继续发送验证码,完成会员信息绑定// BeePlus方会员身份校验APIString toDetectMemberApi = beePlusUserAPIs.getToDetectMemberApi();if (StringUtils.isBlank(toDetectMemberApi)) {throw new CommonBusinessException("toDetectMemberApi配置有误,请核查!");}MemberDetectReqDTO memberDetectReqDTO = new MemberDetectReqDTO();memberDetectReqDTO.setPhone(phone);String jsonPhone = JacksonUtil.toJSon(memberDetectReqDTO);// 校验手机号码为phone的会员是否存在String exists = HttpUtils.doPost(toDetectMemberApi, Objects.requireNonNull(jsonPhone));if (IntegerUtil.toInt(exists) != 1) {throw new CommonBusinessException("手机号码不存在,请移步前台办理会员!");}}// 从Redis取出用户发送短信验证码的间隔时效标识RBucket<Object> bucketDuration = redissonClient.getBucket(Constants.COUNT_DOWN_SEND_SMS_PREFIX + phone);if (bucketDuration.isExists()) {logger.info("AliyunSmsServiceImpl.sendSms ========== 短信验证码发送频繁,限定每{}分钟发送一次 ========== ",Constants.VERIFY_CODE_SEND_DURATION);throw new CommonBusinessException("短信验证码发送频繁,请稍候再试!");}Integer codeType = request.getCodeType();// 可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");String accessKeyId = aliyunSmsProperties.getAccessKeyId();String accessKeySecret = aliyunSmsProperties.getAccessKeySecret();String product = aliyunSmsProperties.getProduct();String domain = aliyunSmsProperties.getDomain();// 短信签名:形如【蜜蜂科技】String smsSign = Constants.SMS_SING;// 初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);// 组装请求对象-具体描述见控制台-文档部分内容SendSmsRequest smsRequest = new SendSmsRequest();// 必填:待发送手机号smsRequest.setPhoneNumbers(phone);// 必填:短信签名-可在短信控制台中找到smsRequest.setSignName(smsSign);// 6位长度随机码String randomCode = RandomUtils.getRandomCode();// 短信调试开关,万能短信验证码 = "1234"if (aliyunSmsProperties.getSimulate()) {randomCode = "1234";}// 使用redis存储,借助其key可设置过期时间// 无论key是否存在,key=value的键始终存在RBucket<Object> randomCodeBucket = redissonClient.getBucket(Constants.VERIFY_CODE_SESSION_PREFIX + phone);// 设置value的同时配置key存活时间randomCodeBucket.set(randomCode, Constants.VERIFY_CODE_VALID_SECONDS, TimeUnit.SECONDS);// 设置短信验证码发送间隔bucketDuration.set(1, Constants.VERIFY_CODE_SEND_DURATION, TimeUnit.MINUTES);// 短信调试开关if (aliyunSmsProperties.getSimulate()) {return true;}// 匹配消息模板chooseSmsTemplate(codeType, smsRequest, randomCode);// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)// smsRequest.setSmsUpExtendCode("90997");// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者// smsRequest.setOutId("yourOutId");// hint 此处可能会抛出异常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(smsRequest);logger.info("AliyunSmsServiceImpl.sendSms =========== sendSmsResponse:{} ===========",JacksonUtil.toJSon(sendSmsResponse));// 短信内容String msgContent = "";//查明细if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {QuerySendDetailsResponse querySendDetailsResponse = querySendDetails(sendSmsResponse.getBizId(), phone);List<QuerySendDetailsResponse.SmsSendDetailDTO> smsSendDetailDTOs = querySendDetailsResponse.getSmsSendDetailDTOs();if (CollectionUtil.isNotEmpty(smsSendDetailDTOs)) {logger.debug("AliyunSmsServiceImpl.sendSms =========== 短信明细查询接口返回数据 ===========");logger.debug("AliyunSmsServiceImpl.sendSms =========== Code:[{}] ===========",querySendDetailsResponse.getCode());logger.debug("AliyunSmsServiceImpl.sendSms =========== Message:[{}] ===========",querySendDetailsResponse.getMessage());for (QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : smsSendDetailDTOs) {logger.info("AliyunSmsServiceImpl.sendSms =========== smsSendDetailDTO:{} ===========",JacksonUtil.toJSon(smsSendDetailDTO));msgContent = smsSendDetailDTO.getContent();}}// 保存短信验证码发送记录smsSendLogDAO.insertSmsSendLog(phone, codeType, randomCode, msgContent, true);return true;} else {smsSendLogDAO.insertSmsSendLog(phone, codeType, randomCode, msgContent, false);return false;}}/*** @return com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse* @throws* @description 查询短信发送记录* @params [bizId, phone]*/private QuerySendDetailsResponse querySendDetails(String bizId, String phone) throws ClientException {// 可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");String accessKeyId = aliyunSmsProperties.getAccessKeyId();String accessKeySecret = aliyunSmsProperties.getAccessKeySecret();String product = aliyunSmsProperties.getProduct();String domain = aliyunSmsProperties.getDomain();//初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);//组装请求对象QuerySendDetailsRequest request = new QuerySendDetailsRequest();//必填-号码request.setPhoneNumber(phone);//可选-流水号request.setBizId(bizId);//必填-发送日期 支持30天内记录查询,格式yyyyMMddSimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");request.setSendDate(ft.format(new Date()));//必填-页大小request.setPageSize(10L);//必填-当前页码从1开始计数request.setCurrentPage(1L);//hint 此处可能会抛出异常,注意catchQuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);return querySendDetailsResponse;}/*** @return void* @throws* @description 根据短信验证码类型,匹配消息模板* @params [codeType, smsRequest, randomCode]*/private void chooseSmsTemplate(Integer codeType, SendSmsRequest smsRequest, String randomCode) {switch (codeType) {case Constants.VerifyCodeType.VERIFY_IDENTITY_CODE://必填:短信模板-可在短信控制台中找到smsRequest.setTemplateCode("SMS_152380369");smsRequest.setTemplateParam("{\"code\":" + randomCode + "}");break;case Constants.VerifyCodeType.LOGIN_CONFIRM_CODE:smsRequest.setTemplateCode("SMS_152380368");smsRequest.setTemplateParam("{\"code\":" + randomCode + "}");break;case Constants.VerifyCodeType.LOGIN_UN_NORMAL_CODE:smsRequest.setTemplateCode("SMS_152380367");smsRequest.setTemplateParam("{\"code\":" + randomCode + "}");break;case Constants.VerifyCodeType.USER_REGISTER_CODE:smsRequest.setTemplateCode("SMS_152380366");smsRequest.setTemplateParam("{\"code\":" + randomCode + "}");break;case Constants.VerifyCodeType.MODIFY_PASSWORD_CODE:smsRequest.setTemplateCode("SMS_152380365");smsRequest.setTemplateParam("{\"code\":" + randomCode + "}");break;case Constants.VerifyCodeType.INFORMATION_CHANGE_CODE:smsRequest.setTemplateCode("SMS_152380364");smsRequest.setTemplateParam("{\"code\":" + randomCode + "}");break;}}}public class Constants {/*** 短信验证类型标识码*/public interface VerifyCodeType {// 验证类型1=> 身份验证int VERIFY_IDENTITY_CODE = 1;// 验证类型2=> 登录确认int LOGIN_CONFIRM_CODE = 2;// 验证类型3=> 登录异常int LOGIN_UN_NORMAL_CODE = 3;// 验证类型4=> 用户注册int USER_REGISTER_CODE = 4;// 验证类型5=> 修改密码int MODIFY_PASSWORD_CODE = 5;// 验证类型6=> 信息变更int INFORMATION_CHANGE_CODE = 6;}
}

阿里云短信服务 发送短信验证码 区分业务场景相关推荐

  1. 使用阿里云的短信服务发送短信

    原文地址使用阿里云的短信服务发送短信 在给客户开发一个信息发送功能的时候,需要涉及到短信的发送,短信发送一般不同的厂商提供的接口不同,处理方式也不太一样,之前用的一个厂商的,提供了一个封装类就很容易发 ...

  2. 如何使用阿里巴巴短信服务发送短信验证码

    关于调用阿里巴巴短信服务发送短信验证的接口的方法: 用户的注册 1.首先我们需要在阿里大于(www.alidayu.com)注册一个账号登录 点击进入控制台 点击使用短信服务 然后需要你申请签名和模板 ...

  3. 阿里云 短信服务——发送短信验证码图文教程

    阿里云短信服务 前言 配置阿里云短信服务 准备工作 1.获取Accesskey 1.2创建子账号 1.2为刚创建的用户分配短信服务的权限 2.1申请签名 2.2申请模板 2.3由于目前还没有使用到系统 ...

  4. 2021最新 使用阿里云的短信服务发送短信

    在给客户开发一个信息发送功能的时候,需要涉及到短信的发送,短信发送一般不同的厂商提供的接口不同,处理方式也不太一样,之前用的一个厂商的,提供了一个封装类就很容易发送短息,因此都是基于HTTP协议做的一 ...

  5. 【无标题】使用阿里云短信服务发送短信

    在给客户开发一个信息发送功能的时候,需要涉及到短信的发送,短信发送一般不同的厂商提供的接口不同,处理方式也不太一样,之前用的一个厂商的,提供了一个封装类就很容易发送短息,因此都是基于HTTP协议做的一 ...

  6. 使用阿里云提供的短信服务发送短信(个人版)

    本人最近需要实现一个注册发短信验证码的功能,找了几家短信服务平台,如腾讯云,云片网等,发现他们都没有提供给用户个人的短信服务权限,申请短信签名等都需要有企业等相关证明,最后找到了阿里云的短信服务平台, ...

  7. 用阿里云短信服务--发送短信demo

    一. AccessKey管理 内容包括:开启子用户AccessKey,创建用户组,给用户组添加sms短信服务权限,创建用户,添加用户到用户组中. 详细操作: 登录阿里云,点击控制台右上角的头像,点击A ...

  8. 【微服务集成阿里SMS短信服务发送短信】

    发送短信项目中很多地方都在使用,所以集成一个单独的服务,如果某个服务需要发送短信只需要依赖短信服务即可. 1.开通阿里SMS短信,创建模板 (省略) 2.创建短信服务 common-server-sm ...

  9. 【使用腾讯云短信服务发送短信】

    有账号直接登录腾讯云,没有账号注册之后登录 搜索短信,点击进入短信控制台 点击免费使用进入控制台,按照概览中的流程操作 创建短信签名,腾讯云支持使用个人公众号创建短信签名,而且有免费条数可以使用,信息 ...

最新文章

  1. h3c wa4320配置上网_企业路由不为人知的功能:自动吸粉、上网监控、多宽带合并...
  2. vue2.0小示例一个~~新鲜出炉哦。欢迎大家留言
  3. go语言中使用递归函数实现文件目录的遍历
  4. 写文件头的算法流程及C代码实现
  5. 转发:Ajax动态画EChart图表
  6. MongoDB入门 - 安装教程
  7. 【假期重磅福利】更新三个Oracle系列课程,共153课时,最低免费获取
  8. cmb网站服务器失去响应代码,3.5.2 连接到服务器并响应各种连接事件(2)
  9. 深度学习与神经网络——邱锡鹏
  10. python有几种容器_Python中几种内置的容器(Containers)类型:列表、字典、集合和元组的比较和该注意的点...
  11. Nginx一个server配置多个location
  12. 数据化管理第一步,你真的会做报表吗?
  13. 232接口针脚定义_VGA接口定义,详细图文资料
  14. VB.NET控件应用编程实例教程(奋斗的小鸟)_PDF 电子书
  15. 金山电脑公司总经理雷军(转载)
  16. 【Matlab创建word文档,插入图注或表注】
  17. 等保2.0三级移动互联安全扩展要求
  18. ac86u原厂固件去广告_释放更多功能,华硕 AC86U 刷官改固件教程
  19. 学了 C 语言到底能做什么, 能从事什么工作?(附课程)
  20. 在Matplotlib中将图片导出

热门文章

  1. intellij idea如何快速格式化代码
  2. 大公司 Or 小公司?
  3. 永中云转换支持PPT动画播放 为文档在线预览多面赋能
  4. php创建wordpress主题,WordPress主题开发之:如何为主题创建一个新的页面模板
  5. mobile 实现横屏竖屏切换--禁止转屏
  6. 专科生适不适合学计算机专业,适合专科生的五大专业是哪些?
  7. TextOut显示多行文本的方法
  8. WIN7系统怎样对硬盘进行分区
  9. CSS 压缩 提高性能的群聊天记录
  10. 智力算法题之病狗问题