springboot 整合腾讯云短信

参考1

准备阶段

获取secretIdsecretKey

在这里插入图片描述

获取签名内容(signName)

在这里插入图片描述

获取模板id(templateId)

在这里插入图片描述

获取应用id(smsSdkAppId)

在这里插入图片描述

代码阶段

该项目所用的依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.tencentcloudapi</groupId>
            <artifactId>tencentcloud-sdk-java</artifactId>
            <version>3.1.390</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yaml

# 腾讯云
tencent:
  sms:
    account:
      secretId: 你的秘钥id
      secretKey: 你的秘钥密码
      smsSdkAppId: 你的应用id
      templateId: 你的模板id
      signName: 你的签名内容
spring:
  redis:
    host: localhost
    port: 6379
    database: 0

TencentSmsProperties

获取yaml中的配置

@Data
@Configuration
@ConfigurationProperties(prefix = "tencent.sms.account")
public class TencentSmsProperties {

    private String secretId;
    private String secretKey;
    private String smsSdkAppId;
    private String templateId;
    private String signName;
}

SmsConfig

@Configuration
public class SmsConfig {

    private static String URL ="sms.tencentcloudapi.com";
    private static final String REGION = "ap-guangzhou";

    @Autowired
    private TencentSmsProperties tencentSmsProperties;

    @Bean
    public SmsClient smsClient(){
        Credential credential = new Credential(tencentSmsProperties.getSecretId(),tencentSmsProperties.getSecretKey());
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setReqMethod("POST");
        httpProfile.setConnTimeout(60);
        httpProfile.setEndpoint(URL);
        // 实例化一个client选项,可选的,没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setSignMethod("HmacSHA256");
        clientProfile.setHttpProfile(httpProfile);
        //实例化 SMS 的 client 对象
        return new SmsClient(credential, REGION, clientProfile);
    }
}

RedisConfig

将验证码缓存到中间件

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        //- 配置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);

        //- 使用Jackson2JsonRedisSerializer实现序列化以及反序列化
        Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();

        //添加自定义序列化和反序列化机制
        //SimpleModule simpleModule = new SimpleModule();
        //simpleModule.addSerializer(DateTime.class,new JodaDateTime2JsonSerializer());
        //simpleModule.addDeserializer(DateTime.class,new JodaDateTime2JsonDeserializer());
        //objectMapper.registerModule(simpleModule);

        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //会生成字段类的信息
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(objectMapper);

        //将String类型的key和value序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jsonRedisSerializer);

        //将Hash类型的hashKey和hashValue序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);

        return redisTemplate;
    }
}

KaptchaConfig

生成验证码

@Configuration
public class KaptchaConfig {

    @Bean
    Producer producer(){
        Properties properties = new Properties();
        properties.setProperty("kapcha.image.width","150");
        properties.setProperty("kapcha.image.height","50");
        //文本集合,验证码值从此集合中获取
        properties.setProperty("kaptcha.textproducer.char.string", "0123456789");
        //验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

service层

public interface SmsService {

    String sendSms(String phone);

    boolean validateCode(String phone,String code);
}

System.out.println(response.getSendStatusSet()[0].getCode());
如果报错注意看报错的原因。
在页面ctrl+f搜索你报错的code
我遇到两个坑:

  1. FailedOperation.SignatureIncorrectOrUnapproved
  2. 验证码只能为纯数字。
@Service
@Slf4j
public class SmsServiceImpl implements SmsService{

    @Autowired
    private TencentSmsProperties smsProperties;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private Producer producer;

    @Autowired
    private SmsClient smsClient;

    @Override
    public String sendSms(String phone) {
        String[] phoneNumberSet = {"+86"+phone};
        //生成随机验证码
        String code = producer.createText();
        //将code添加到参数数组(取决于你的短信模板有多少个参数),验证码只能纯数字
        String[] templateParamSet = {code,"5"};
        //实例请求,组装参数
        SendSmsRequest req = new SendSmsRequest();
        req.setTemplateID(smsProperties.getTemplateId());
        req.setSmsSdkAppid(smsProperties.getSmsSdkAppId());
        req.setSign(smsProperties.getSignName());
        //yaml文件读取中文会乱码
        //req.setSign("个人学习记录");
        //发送的手机号
        req.setPhoneNumberSet(phoneNumberSet);
        //发送的内容(验证码)
        req.setTemplateParamSet(templateParamSet);

        try {
            //发送短信
            SendSmsResponse response = smsClient.SendSms(req);
            // 输出json格式的字符串回包
            System.out.println(SendSmsResponse.toJsonString(response));

            // 也可以取出单个值,你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
            System.out.println(response.getSendStatusSet()[0].getCode());
            //存入redis
            redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
            return "OK";
        } catch (TencentCloudSDKException e) {
            log.error("发送失败,或者剩余短信数量不足", e);
        }
        return "发送失败,或者剩余短信数量不足";
    }

    @Override
    public boolean validateCode(String phone, String code) {
        String data = (String) redisTemplate.opsForValue().get(phone);
        return code.equals(data);
    }
}

controller层

@RestController
@RequestMapping("/sms")
public class SmsController {

    @Autowired
    private SmsService smsService;


    @GetMapping("/send")
    public String sendSms(String phone){
        return smsService.sendSms(phone);
    }

    @GetMapping("/validate")
    public String validate(String phone,String code){
        if (smsService.validateCode(phone, code)){
                return "验证码正确";
            }
        return "验证码错误";
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值