Springboot3整合腾讯云短信服务


前言

在日常的开发中,我们经常会有发送验证码的需求,这时候就需要借助第三方服务了。腾讯云为我们提供了短信服务,我们只需要在springboot中整合便可。


一、在腾讯云注册短信服务

腾讯短信服务

这里不做过多的介绍,提示:这里如果只是作测试用,那么可以申请一个微信公众号,申请签名会方便很多。

二、具体使用步骤

(1)引入pom文件

		<dependency>
            <groupId>com.github.qcloudsms</groupId>
            <artifactId>qcloudsms</artifactId>
            <version>1.0.6</version>
        </dependency>

(2)配置yaml文件(短信发送参数)

txsms:
  AppId: 0000000000 # 你的系统默认应用SDK AppID
  AppKey: "0000000000000000000000000" # 你的系统默认应用App Key
  TemplateIdLogin: 00000000 # 登陆正文模板ID
  TemplateIdRegister: 00000000 # 注册正文模板ID
  signName: "顾娜拉黑暗之神公众号" # 你的签名内容

(3)编写参数配置类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**腾讯云发送短信
 * 参数配置类
 * @author: 顾壮壮
 * @version:v1.0
 * @date: 2023/7/6 14:21
 */
@Data
// 读取application.yml中的txsms的属性
@ConfigurationProperties(prefix = "txsms")
public class TxProperties {
    // AppId
    private int AppId;
    // 短信应用SDK AppKey
    private String AppKey;
    // 登陆短信模板ID
    private int TemplateIdLogin;
    // 注册短信模板ID
    private int TemplateIdRegister;
    // 签名
    private String signName;
}

(4)编写TxSmsTemplate类

编写内置功能模板:登录

import com.example.springbootmessage.pojo.SMS;
import com.example.springbootmessage.pojo.TxProperties;
import com.example.springbootmessage.utils.RedisCache;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @description:腾讯云发送短信模板对象,封装了发送短信的api
 * @author: 顾壮壮
 * @date: 2023/7/6 14:26
 */
@Slf4j
@Component
public class TxSmsTemplate {

    private TxProperties txProperties;

    public TxSmsTemplate(TxProperties txProperties) {
        this.txProperties = txProperties;
    }
	
	//引入redis缓存验证码
    @Autowired
    private RedisCache redisCache;


    /**
     * 登陆验证
     * @param phoneNumber 手机号
     * @param code 验证码
     * @return
     */
    public boolean loginSmsSend(String phoneNumber,String code){
        try {
            // 模板参数
            String[] params = {code};

            // 构建短信发送器
            SmsSingleSender ssender = new SmsSingleSender(txProperties.getAppId(), txProperties.getAppKey());
            //sendWithParm:     传入国家码 电话号码 模板id 模板参数 签名 扩展码为空 返回参数为空
            SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumber,
                    txProperties.getTemplateIdLogin(), params, txProperties.getSignName(), "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信

            if(result.result==0){
                //将登陆的手机号存入redis中
                redisCache.setCacheObject("loginPhone",new SMS(phoneNumber,code),5, TimeUnit.MINUTES);
                return true;
            }else{
                System.out.println("短信发送失败,原因:"+result.errMsg);
            }
        } catch (HTTPException e) {
            // HTTP响应码错误
            log.info("短信发送失败,HTTP响应码错误!");
            // e.printStackTrace();
        } catch (JSONException e) {
            // json解析错误
            log.info("短信发送失败,json解析错误!");
            //e.printStackTrace();
        } catch (IOException e) {
            // 网络IO错误
            log.info("短信发送失败,网络IO错误!");
            // e.printStackTrace();
        }
        return false;
    }
}
  • 其中封装了一个SMS pojo类用于存储电话号码和验证码
  • 还封装了一个redis工具类RedisCache
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @description:封装一个实体类对象用于存储电话号码和验证码
 * @author: 顾壮壮
 * @date: 2023/7/6 15:14
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SMS implements Serializable {
    //存入的电话号码
    private String phone;
    //存入redis的验证码
    private String code;
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * spring redis 工具类
 *
 * @author ruoyi
 **/
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
public class RedisCache {
    @Autowired
    public RedisTemplate redisTemplate;
    
    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }
    
    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @param unit    时间单位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

	/**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }
}

(5)编写配置类

目的是将TxSmsTemplate模板类和TxProperties实体类注入容器中,交给springboot管理,这样,也是为了使yaml配置文件的数据赋值到TxProperties实体类,使模板类可以使用数据

import com.example.springbootmessage.pojo.TxProperties;
import com.example.springbootmessage.service.TxSmsTemplate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 自动配置类
 * 配置工具类 template
 */
@Configuration
@EnableConfigurationProperties({TxProperties.class})
public class CommonsAutoConfiguration {

    /*
     * @description:创建发送短信的工具类将TxProperties对象注入到容器中
     * @author: 顾壮壮
     * @date: 2023/7/6 14:29
     * @param txProperties
     * @return: com.example.springbootmessage.service.TxSmsTemplate
    */
    //这里其实有可以不用@Bean注入容器,直接在TxProperties类和TxSmsTemplate类上标注@Component注解,
    //直接便可以注入容器中,我这里使用有参构造,将TxProperties和TxSmsTemplate都注入到容器中
    @Bean
    public TxSmsTemplate txSmsTemplate(TxProperties txProperties) {
        return new TxSmsTemplate(txProperties);
    }
}

三、测试

@Slf4j
@SpringBootTest
class SpringbootMessageApplicationTests { ;
    @Autowired
    private TxSmsTemplate txSmsTemplate;
    @Autowired
    private RedisCache redisCache;
    /**
     * 腾讯云发送短信测试
     */
    @Test
    public void TxSmsTest(){
        boolean Msg = txSmsTemplate.loginSmsSend("测试的电话号码", ValidateCodeUtils.generateValidateCode(6));
        //返回true 或者 false
        System.out.println(Msg);
        //取出验证码
        Object loginPhone = redisCache.getCacheObject("loginPhone");
        SMS sms=new ObjectMapper().convertValue(loginPhone, SMS.class);
        //判断是否超过了五分钟,超过返回null
        if (sms!=null)System.out.println(sms.getCode());
        else log.info("loginPhone对象不存在或超过了五分钟!");
    }
}

这里编写了一个ValidateCodeUtils类,用于随机生成验证码

import java.util.Random;

/**
 * @description:
 * @author: 顾壮壮
 * @date: 2023/6/29 14:59
 */
public class ValidateCodeUtils {
    /**
     * 随机生成验证码
     * @param length 长度为4位或者6位
     * @return
     */
    public static String generateValidateCode(int length){
        Integer code =null;

//      长度为4
        if(length == 4){
            code = new Random().nextInt(9999);//生成随机数,最大为9999
            if(code < 1000){
                code = code + 1000;//保证随机数为4位数字
            }

//      长度为6
        }else if(length == 6){
            code = new Random().nextInt(999999);//生成随机数,最大为999999
            if(code < 100000){
                code = code + 100000;//保证随机数为6位数字
            }
//       其他情况
        }else{
            throw new RuntimeException("只能生成4位或6位数字验证码");
        }
        return Integer.toString(code);
    }

    /**
     * 随机生成指定长度字符串验证码
     * @param length 长度
     * @return
     */
    public static String generateValidateCode4String(int length){
        Random rdm = new Random();
        String hash1 = Integer.toHexString(rdm.nextInt());
        String capstr = hash1.substring(0, length);
        return capstr;
    }
}

总结

本篇文章是个人对使用腾讯云短信的总结,之前走过一点弯路,希望大家看完这篇文章,不会走错路,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gunalaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值