腾讯云短信服务

  • 本来是打算使用阿里云的短信服务,但是审核比较严格一直通不过。所以又研究了下腾讯云的短信服务。发现腾讯云审核比较松,还免费赠送200条试用短信,这对于学生党开发测试来说是非常不错了

开通服务

  • 注册登录腾讯云官网:https://cloud.tencent.com/,需要实名认证
  • 然后搜索【短信】服务并开通,然后进入【短信控制台】,查看短信余额

  • 在左侧【国内短信】-【签名管理】创建签名,本人是使用网站审核,上传备案截图即可。审核很快,一天就搞定

  • 然后再创建模板即可

获取密钥

  • 左侧【应用管理】-【应用列表】,默认都有,没有就创建。点击应用,查看【应用信息】,保存SDKAppIDApp Key,后面会用到

  • 然后在头像下拉框里点击【访问管理】
  • 左侧【访问密钥】下【API密钥管理】,弹出框选择【选择继续使用】,没有密钥需要新建一个

  • SecretId 用于标识 API 调用者的身份,SecretKey 用于加密签名字符串和服务器端验证签名字符串的密钥

Java接入开发

相关依赖

1
2
3
4
5
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>4.0.11</version> <!--最新版本-->
</dependency>

工具类

  • 创建一个生成4或6位数字验证码的工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 验证码随机数工具类
public class ValidateCode {
public static Integer generateValidateCode(int length){
Integer code = null;
if(length == 4){
code = new Random().nextInt(9999); //生成随机数,最大为9999
if(code < 1000){
code = code + 1000; //保证随机数为4位数字
}
}else if(length == 6){
code = new Random().nextInt(999999); //生成随机数,最大为999999
if(code < 1000000){
code = code + 100000; //保证随机数为6位数字
}
}else{
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
}
  • 再创建一个封装参数的常量类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 参数常量类
public class Constants {
// 腾讯云账户密钥对:SecretID
public static final String SecretID = "AKIDyhngxxxxf3KR";
// 腾讯云账户密钥对:Secretkey
public static final String SecretKey = "Zu1tqeEZbMxxxBYeBOO7";;
// 应用 SDKAppId
public static final String SDKAppID = "14xxx4195";
// singName 签名
public static final String signName = "xiaoliblog";
// 短信模板ID
public static final String templateId = "10xxx88";
// 效验码,用于保存和校验
public static String validateCode = "";
}
  • 封装一个短信发送的工具类,详情参考官方文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package com.lzy.utils;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
//导入可选配置类
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
// 导入要请求接口对应的request response类
import com.tencentcloudapi.sms.v20190711.SmsClient;
// 导入要请求接口对应的request response类
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;

public class SendSmsUtil {

public static SendStatus[] sendSms(String[] phoneNumber ) {

SendStatus[] returString= {};

try {
/* 必要步骤:
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
* 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
* 以免泄露密钥对危及你的财产安全。
* CAM密匙查询: https://console.cloud.tencent.com/cam/capi*/
Credential cred = new Credential(Constants.SecretID, Constants.SecretKey);

// 实例化一个http选项,可选,没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();

// 设置代理
//httpProfile.setProxyHost("host");
//httpProfile.setProxyPort(port);
/* SDK默认使用POST方法。
* 如果你一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求 */
httpProfile.setReqMethod("POST");
/* SDK有默认的超时时间,非必要请不要进行调整
* 如有需要请在代码中查阅以获取最新的默认值 */
httpProfile.setConnTimeout(60);
/* SDK会自动指定域名。通常是不需要特地指定域名的,但是如果你访问的是金融区的服务
* 则必须手动指定域名,例如sms的上海金融区域名: sms.ap-shanghai-fsi.tencentcloudapi.com */
httpProfile.setEndpoint("sms.tencentcloudapi.com");

/* 非必要步骤:
* 实例化一个客户端配置对象,可以指定超时时间等配置 */
ClientProfile clientProfile = new ClientProfile();
/* SDK默认用TC3-HMAC-SHA256进行签名
* 非必要请不要修改这个字段 */
clientProfile.setSignMethod("HmacSHA256");
clientProfile.setHttpProfile(httpProfile);
/* 实例化要请求产品(以sms为例)的client对象
* 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,或者引用预设的常量 */
SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
/* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
* 你可以直接查询SDK源码确定接口有哪些属性可以设置
* 属性可能是基本类型,也可能引用了另一个数据结构
* 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明 */
SendSmsRequest req = new SendSmsRequest();

/* 填充请求参数,这里request对象的成员变量即对应接口的入参
* 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
* 基本类型的设置:
* 帮助链接:
* 短信控制台: https://console.cloud.tencent.com/sms/smslist
* sms helper: https://cloud.tencent.com/document/product/382/3773 */

/* 短信应用ID: 短信SdkAppid在 [短信控制台] 添加应用后生成的实际SdkAppid,示例如1400006666 */
String sdkappid = Constants.SDKAppID;
req.setSmsSdkAppid(sdkappid);

/* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看 */
String sign = Constants.signName;
req.setSign(sign);

/* 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper] */
//String senderid = "";
//req.setSenderId(senderid);

/* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回 */
//String session = "xxx";
//req.setSessionContext(session);

/* 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper] */
//String extendcode = "xxx";
//req.setExtendCode(extendcode);

/* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */
String templateID = Constants.templateId;
req.setTemplateID(templateID);

/* 下发手机号码,采用 e.164 标准,+[国家或地区码][手机号]
* 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号*/
String[] phoneNumbers = {"+86"+phoneNumber};
req.setPhoneNumberSet(phoneNumber);

//随机验证码
int vode=ValidateCode.generateValidateCode(6);
String code=String.valueOf(vode);
Constants.validateCode = code;

/* 模板参数: 若无模板参数,则设置为空*/
String[] templateParams = {code};
req.setTemplateParamSet(templateParams);

/* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
* 返回的 res 是一个 SendSmsResponse 类的实例,与请求对象对应 */
SendSmsResponse res = client.SendSms(req);

// 输出json格式的字符串回包
System.out.println(SendSmsResponse.toJsonString(res));

// 也可以取出单个值,你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
System.out.println(res.getRequestId());
returString=res.getSendStatusSet();

} catch (TencentCloudSDKException e) {
e.printStackTrace();
}

return returString;
}
}

发送测试

  • 编写一个控制类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Controller
public class SmsController {
@RequestMapping({"/","/index"})
public String toIndex(){
return "index";
}

@RequestMapping(value = "/sendCode")
@ResponseBody
public SendStatus[] sendCode(@RequestParam(value = "telephone",required = true) String phone){
String phones[] = {"+86" + phone};
SendStatus ret[] = SendSmsUtil.sendSms(phones);
return ret;
}
}
  • 前端发送表单
1
2
3
4
<form action="/sendCode" method="post">
<input type="text" name="telephone">
<input type="submit">
</form>
  • 测试结果如下,
1
[{"message":"send success","sessionContext":"","code":"Ok","phoneNumber":"+8617891027887","fee":1,"isoCode":"CN","serialNo":"2433:90431553816256315043912788"}]