本文主要对SpringBoot2.x集成腾讯云短信进行简单总结,其中SpringBoot使用的2.4.5版本。

一、腾讯云短信简介

腾讯云短信(Short Message Service,SMS)沉淀腾讯十多年短信服务技术和经验,为QQ、微信等亿级平台和10万+客户提供快速灵活接入的高质量的国内短信与国际/港澳台短信服务。

  • 国内短信验证秒级触达,99%到达率。
  • 国际/港澳台短信覆盖全球200+国家/地区,稳定可靠。

单次短信的业务请求流程如下所示:

短信由签名和正文内容组成,发送短信前需要申请短信签名和正文内容模板。短信签名是位于短信正文前【】中的署名,用于标识公司或业务。短信签名需要审核通过后才可使用。短信模板即具体发送的短信正文内容,短信模板支持验证码模板、通知类短信模板和营销短信模板。短信内容可以通过模板参数实现个性化定制。短信模板申请前需要先申请短信签名,短信模板需要审核通过后才可使用。

二、准备工作

1.开通短信服务

如果没有腾讯云账号,需要注册腾讯云账号,并完成实名认证,可以个人认证和企业认证,不能进行企业认证的话也可以进行个人认证。然后进入腾讯云短信控制台,开通短信服务,开通短信和个人认证之后分别都会赠送包含100条短信的国内套餐包,用来测试足够:

2.创建签名

这里创建国内短信签名,创建完成后等到状态变为已通过就可以使用了:

创建签名时签名类型可以选网站、APP、公众号和小程序,可以根据需要创建:

3.创建正文模板

创建模板,创建完成之后状态变为已通过就可以使用了:

模板内容可以使用标准模板也可以自定义:

4.创建短信应用

在应用列表下可以创建短信应用,获取短信应用的SDKAppID:

点击应用可以查看应用信息:

5.腾讯云API密钥

在访问管理菜单的访问密钥下的API密钥管理中可以新建和查看API密钥,在请求腾讯云短信服务发送短信时需要传入该密钥:

三、集成腾讯云短信

通过Maven新建一个名为springboot-tencent-sms的项目。

1.引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 腾讯云 Java SDK 依赖 -->
<dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>3.1.297</version>
</dependency>
<!-- Spring Data Redis 起步依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lombok插件 -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.8</version>
</dependency>

2.编写配置类

用于读取配置文件中的自定义腾讯云短信配置的配置类:

package com.rtxtitanv.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.config.SmsConfig* @description 腾讯云短信配置类* @date 2021/6/25 16:21*/
@ConfigurationProperties(prefix = "tencent.sms")
@Configuration
@Data
public class SmsConfig {/*** 腾讯云API密钥的SecretId*/private String secretId;/*** 腾讯云API密钥的SecretKey*/private String secretKey;/*** 短信应用的SDKAppID*/private String appId;/*** 签名内容*/private String sign;/*** 模板ID*/private String templateId;/*** 过期时间*/private String expireTime;/*** redis存储的key的前缀*/private String phonePrefix;
}

Redis配置类:

package com.rtxtitanv.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import javax.annotation.Resource;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.config.RedisConfig* @description Redis配置类* @date 2021/6/26 12:24*/
@Configuration
public class RedisConfig {@Resourceprivate RedisConnectionFactory redisConnectionFactory;/*** RedisTemplate实例** @return RedisTemplate实例*/@Beanpublic RedisTemplate<String, Object> redisTemplate() {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();initRedisTemplate(redisTemplate, redisConnectionFactory);return redisTemplate;}/*** 设置数据存入redis的序列化方式** @param redisTemplate RedisTemplate对象* @param factory       RedisConnectionFactory对象*/private void initRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setConnectionFactory(factory);}
}

3.编写配置文件

spring:redis:host: 127.0.0.1port: 6379# 自定义腾讯云短信配置
tencent:sms:# 配置腾讯云API密钥的SecretIdsecretId: 这里填腾讯云API密钥的SecretId# 配置腾讯云API密钥的SecretKeysecretKey: 这里填腾讯云API密钥的SecretKey# 配置短信应用的SDKAppIDappId: 这里填短信应用的SDKAppID# 配置签名内容sign: "这里填签名内容"# 配置模板IDtemplateId: 这里填模板ID# 配置过期时间expireTime: 5# 配置redis存储的key的前缀phonePrefix: REGIST

4.编写工具类

腾讯云短信工具类:

package com.rtxtitanv.util;import com.rtxtitanv.config.SmsConfig;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.util.SmsUtil* @description 腾讯云短信工具类* @date 2021/6/25 16:21*/
public class SmsUtil {private static final Logger LOGGER = LoggerFactory.getLogger(SmsUtil.class);/*** 发送短信** @param smsConfig      腾讯云短信配置对象* @param templateParams 模板参数* @param phoneNumbers   手机号数组* @return SendStatus[],短信发送状态*/public static SendStatus[] sendSms(SmsConfig smsConfig, String[] templateParams, String[] phoneNumbers) {try {// 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。Credential cred = new Credential(smsConfig.getSecretId(), smsConfig.getSecretKey());// 实例化一个http选项,可选,没有特殊需求可以跳过HttpProfile httpProfile = new HttpProfile();// SDK默认使用POST方法httpProfile.setReqMethod("POST");// SDK有默认的超时时间,非必要请不要进行调整httpProfile.setConnTimeout(60);// 非必要步骤:实例化一个客户端配置对象,可以指定超时时间等配置ClientProfile clientProfile = new ClientProfile();// SDK默认用TC3-HMAC-SHA256进行签名,非必要请不要修改这个字段clientProfile.setSignMethod("HmacSHA256");clientProfile.setHttpProfile(httpProfile);// 实例化要请求产品(以sms为例)的client对象,第二个参数是地域信息,可以直接填写字符串ap-guangzhou,或者引用预设的常量SmsClient smsClient = new SmsClient(cred, "ap-guangzhou", clientProfile);// 实例化一个请求对象SendSmsRequest req = new SendSmsRequest();// 设置短信应用ID:短信SdkAppId在[短信控制台]添加应用后生成的实际SdkAppIdreq.setSmsSdkAppId(smsConfig.getAppId());// 设置短信签名内容:使用UTF-8编码,必须填写已审核通过的签名,签名信息可登录[短信控制台]查看req.setSignName(smsConfig.getSign());// 设置国际/港澳台短信SenderId:国内短信填空,默认未开通req.setSenderId("");// 设置模板ID:必须填写已审核通过的模板ID。模板ID可登录[短信控制台]查看req.setTemplateId(smsConfig.getTemplateId());// 设置下发手机号码,采用E.164标准,+[国家或地区码][手机号]req.setPhoneNumberSet(phoneNumbers);// 设置模板参数:若无模板参数,则设置为空req.setTemplateParamSet(templateParams);// 通过client对象调用SendSms方法发起请求。注意请求方法名与请求对象是对应的,返回的res是一个SendSmsResponse类的实例,与请求对象对应SendSmsResponse res = smsClient.SendSms(req);// 控制台打印日志输出json格式的字符串回包LOGGER.info(SendSmsResponse.toJsonString(res));return res.getSendStatusSet();} catch (TencentCloudSDKException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}}
}

Redis工具类:

package com.rtxtitanv.util;import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.util.RedisUtil* @description Redis工具类* @date 2021/6/26 12:24*/
@Component
public class RedisUtil {@Resourceprivate RedisTemplate<String, Object> redisTemplate;/*** 缓存基本对象** @param key    键* @param value  值* @param expire 键的过期时间*/public void setCacheObject(String key, Object value, long expire) {redisTemplate.opsForValue().set(key, value);if (expire > 0) {redisTemplate.expire(key, expire, TimeUnit.MINUTES);}}/*** 获取指定键的缓存对象** @param key 键* @return 缓存对象*/public Object getCacheObject(String key) {return redisTemplate.opsForValue().get(key);}/*** 判断键是否存在并且未过期** @param key 键* @return true,键存在并且未过期;false,键不存在或存在但过期*/public boolean hasKey(String key) {return redisTemplate.hasKey(key) && getExpire(key) > 0 ? true : false;}/*** 获取键的过期时间** @param key 键* @return 过期时间*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.MINUTES);}/*** 删除指定键的缓存** @param key 键*/public void delete(String key) {redisTemplate.delete(key);}/*** 创建缓存的键** @param prefix      前缀* @param phoneNumber 手机号* @return 键*/public static String createCacheKey(String prefix, String phoneNumber) {return prefix + phoneNumber;}
}

用于生成随机验证码的工具类:

package com.rtxtitanv.util;import java.util.Random;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.util.RandomUtil* @description Random工具类* @date 2021/6/26 11:39*/
public class RandomUtil {private static final Random RANDOM = new Random();/*** 生成指定位数的随机数字字符串** @param length 字符串长度* @return 随机数字字符串*/public static String randomNumbers(int length) {StringBuilder randomNumbers = new StringBuilder();for (int i = 0; i < length; i++) {randomNumbers.append(RANDOM.nextInt(10));}return randomNumbers.toString();}
}

5.Controller层

package com.rtxtitanv.controller;import com.rtxtitanv.service.SmsService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.controller.SmsController* @description SmsController* @date 2021/6/25 16:20*/
@RequestMapping("/sms")
@RestController
public class SmsController {@Resourceprivate SmsService smsService;@PostMapping("/send")public String sendSmsCode(@RequestParam(value = "phoneNumber") String phoneNumber) {return smsService.sendSmsCode(phoneNumber);}@PostMapping("/verify")public String verifySmsCode(@RequestParam(value = "phoneNumber") String phoneNumber,@RequestParam(value = "smsCode") String smsCode) {return smsService.verifySmsCode(phoneNumber, smsCode);}
}

6.Service层

package com.rtxtitanv.service;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.service.SmsService* @description SmsService* @date 2021/6/25 16:20*/
public interface SmsService {/*** 发送短信验证码** @param phoneNumber 手机号* @return*/String sendSmsCode(String phoneNumber);/*** 验证短信验证码** @param phoneNumber 手机号* @param smsCode     短信验证码* @return*/String verifySmsCode(String phoneNumber, String smsCode);
}
package com.rtxtitanv.service.impl;import com.rtxtitanv.config.SmsConfig;
import com.rtxtitanv.service.SmsService;
import com.rtxtitanv.util.RandomUtil;
import com.rtxtitanv.util.RedisUtil;
import com.rtxtitanv.util.SmsUtil;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** @author rtxtitanv* @version 1.0.0* @name com.rtxtitanv.service.impl.SmsServiceImpl* @description SmsService实现类* @date 2021/6/25 16:20*/
@Service
public class SmsServiceImpl implements SmsService {@Resourceprivate SmsConfig smsConfig;@Resourceprivate RedisUtil redisUtil;@Overridepublic String sendSmsCode(String phoneNumber) {// 下发手机号码,采用e.164标准,+[国家或地区码][手机号]String[] phoneNumbers = {"+86" + phoneNumber};// 生成6位随机数字字符串String smsCode = RandomUtil.randomNumbers(6);// 模板参数:若无模板参数,则设置为空(参数1为随机验证码,参数2为有效时间)String[] templateParams = {smsCode, smsConfig.getExpireTime()};// 发送短信验证码SendStatus[] sendStatuses = SmsUtil.sendSms(smsConfig, templateParams, phoneNumbers);if ("Ok".equals(sendStatuses[0].getCode())) {// 创建缓存的keyString key = RedisUtil.createCacheKey(smsConfig.getPhonePrefix(), phoneNumber);// 将验证码缓存到redis并设置过期时间redisUtil.setCacheObject(key, smsCode, Long.parseLong(smsConfig.getExpireTime()));return "验证码发送成功";} else {return "验证码发送失败:" + sendStatuses[0].getMessage();}}@Overridepublic String verifySmsCode(String phoneNumber, String smsCode) {// 创建keyString key = RedisUtil.createCacheKey(smsConfig.getPhonePrefix(), phoneNumber);// 判断指定key是否存在并且未过期if (redisUtil.hasKey(key)) {// 验证输入的验证码是否正确if (smsCode.equals(redisUtil.getCacheObject(key))) {// 验证成功后删除验证码缓存redisUtil.delete(key);return "验证成功";} else {return "验证码错误";}} else {return "验证码已失效";}}
}

四、腾讯云短信测试

运行项目,使用Postman进行接口测试。

1.发送短信验证码

发送如下POST请求以请求腾讯云短信服务向指定手机号发送短信验证码,请求地址为http://localhost:8080/sms/send

Redis客户端查看发现验证码已经存到了Redis中:

手机上也成功收到了验证码,说明发送短信成功:

2.验证短信验证码

发送如下POST请求验证短信验证码,请求地址为http://localhost:8080/sms/verify,这里将验证码参数smscode设为不同于之前发送到手机的验证码来模拟验证码输入错误:

再次发送如下POST请求验证短信验证码,这里输入正确的验证码:

Redis客户端刷新发现验证码缓存已经删除:

再次发送如下POST请求验证短信验证码,发现验证码已失效,满足短信验证码验证成功后就失效的业务需求:

代码示例

  • Github:https://github.com/RtxTitanV/springboot-learning/tree/master/springboot2.x-learning/springboot-tencent-sms
  • Gitee:https://gitee.com/RtxTitanV/springboot-learning/tree/master/springboot2.x-learning/springboot-tencent-sms

SpringBoot2.x 集成 腾讯云短信相关推荐

  1. 使用springboot集成腾讯云短信服务,解决配置文件读取乱码问题

    使用springboot集成腾讯云短信服务,解决配置文件读取乱码问题 参考文章: (1)使用springboot集成腾讯云短信服务,解决配置文件读取乱码问题 (2)https://www.cnblog ...

  2. springboot+sms 集成腾讯云短信平台

    springboot+sms 集成腾讯云短信平台实现发送短信功能 一.申请短信功能 到腾讯云管理平台申请短信功能(https://console.cloud.tencent.com/) 1.1 创建短 ...

  3. 快速集成腾讯云短信实现短信发送(Spring Boot)

    前言 腾讯云活动白嫖 1.地址 地址:https://cloud.tencent.com/act/free?from=14600 2.创建签名(根据实际情况选择) 我的是网站 3.创建模板 选择模板内 ...

  4. SpringBoot集成腾讯云短信实现注册/登录功能

    前言 笔记参考 Duktig丶 JavaSDK地址:短信 Java SDK - SDK 文档 - 文档中心 - 腾讯云 1.导入依赖 <dependency><groupId> ...

  5. 轻松集成腾讯云短信服务实现短信发送(Java实现)

    不论是阿里云还是腾讯云,要想在网站上实现短信发送功能,首先得保证你的网站域名是通过备案的,因为短信签名是需要用到备案过的域名截图,所以域名通过了,申请很快就会审批成功了. (至于备案的话,需要你先购买 ...

  6. SpringBoot工程接入腾讯云短信服务平台

    由于业务需要,需要使用第三方短信平台,进行验证码的发送.网上的短信服务平台主要由:百度.腾讯.阿里云:采用官方提供的SDK,调用接口即可. 腾讯云短信服务平台和阿里云短信服务平台,一般步骤为:注册-- ...

  7. 接入腾讯云短信服务(史上最详细+该短信服务如何申请成功+发送短信验证码API讲解+相关错误分析)

    2021/8/17/23:01{2021/8/17/23:01}2021/8/17/23:01 文章目录 前言 一.如何成功申请到腾讯云短信服务 1.签名申请 2.正文模板申请 二.发送短信API开发 ...

  8. SpringBoot腾讯云短信实现验证码

    SpringBoot腾讯云短信实现验证码 在学习过程中偶然遇见需要实现验证码功能的需求,于是寻思着将功能抽取出来用于分享学习 业务功能:实现验证码60s,且要求防止用户高频刷验证码(即1min一次不多 ...

  9. 普歌-腾讯云短信+使用node发送短信(3种方法API、SDK)、封装工具、搭建web服务、写接口、调用接口发送短信、时效性判断、验证验证码的正确性(下)

    普歌-结合腾讯云短信服务+node搭建一个简单的发送短信web小项目 涉及技术: 腾讯云服务 后端服务:node+express 前端搭建:html+js 前言:本来这篇博客应该很早就发了,中间有一些 ...

  10. Spring Boot腾讯云短信申请

    1.在pom.xml文件中添加依赖 <dependency><groupId>com.tencentcloudapi</groupId><artifactId ...

最新文章

  1. jQuery中的插件机制
  2. 人脸特征值能存放在sql server中吗_钥匙丢了进不了门,Out了!只要自己没丢就能进门...
  3. 分解得到的时频域特征_【推荐文章】基于变分模态分解和广义Warblet变换的齿轮故障诊断...
  4. Linux系统安全审计工具Lynis
  5. mysql 数值类型 长度_mysql中的数据类型的长度
  6. 数据中心布线系统的整体规划
  7. LiveVideoStackCon 一次全新的尝试,错过了就是一辈子
  8. Django创建项目后,项目文件夹下的组成部分
  9. android内置t卡中预制资源,[FAQ17514][Recovery]Recovery mode FAQ搜寻指南
  10. 好吧,你说简单就简单,但简单的事,不要变成本能,要常思常变
  11. java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice
  12. shell中的重定向(21)
  13. MYSQL 最大连接数设置
  14. linux更改445端口,windows连接非445端口(nginx转发)的samba服务卡顿
  15. 抖音短视频怎么吸粉 手把手教你快速抖音养号吸粉引流
  16. windows 搭建Web服务器和连接局域网打印机
  17. 如何注册腾讯云个人账号(图文教程)
  18. 上海跃兔网络科技有限公司简介
  19. 新式单片机视频教程下载
  20. spring IOC和DI区别

热门文章

  1. 小程序服务器装rsshub,RssHub 部署
  2. amd支持服务器内存,AMD专用内存为什么只能在AMD平台使用?与普通内存有什么区别?...
  3. 新版标准日本语初级_第四十五课
  4. 计算摄影 | 摄像机成像原理及参数解析
  5. 操作系统的概念(定义)
  6. java判断名字是否为张三_现有5个学生{张三,李四,王五,那六,小七}的数组,输入一个姓名,检查姓名是否存在,如果java啊...
  7. openlayers学习——13、openlayers比例尺
  8. 【python】使用python绘制地图时手动添加比例尺
  9. 保温杯市场前景分析及行业研究报告
  10. 抖音小程序是什么_如何开发抖音小程序