集成腾讯云短信接口方法
This commit is contained in:
parent
b0583d969e
commit
33ff284943
7
pom.xml
7
pom.xml
|
@ -193,13 +193,6 @@
|
||||||
<version>${ruoyi.version}</version>
|
<version>${ruoyi.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.tencentcloudapi</groupId>
|
|
||||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
|
||||||
<version>${tencent.version}</version>
|
|
||||||
<scope>system</scope>
|
|
||||||
<systemPath>F:/xxhy/RuoYi-Vue/libs/tencentcloud-sdk-java-3.1.1039.jar</systemPath>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.tencentcloudapi</groupId>
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||||
|
|
|
@ -7,7 +7,6 @@ import javax.annotation.Resource;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.ruoyi.system.service.SmsService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.util.FastByteArrayOutputStream;
|
import org.springframework.util.FastByteArrayOutputStream;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -42,9 +41,6 @@ public class CaptchaController
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysConfigService configService;
|
private ISysConfigService configService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SmsService smsService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成验证码
|
* 生成验证码
|
||||||
*/
|
*/
|
||||||
|
@ -98,8 +94,4 @@ public class CaptchaController
|
||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*发送短信验证码*/
|
|
||||||
public void sendVerificationCode(String phoneNumber){
|
|
||||||
smsService.sendVerificationCode(phoneNumber);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.ruoyi.web.controller.common;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
|
import com.ruoyi.system.service.ISmsService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Api("短信模块")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/sms")
|
||||||
|
public class SmsController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISmsService iSmsService;
|
||||||
|
|
||||||
|
@PostMapping("sendSms")
|
||||||
|
@ApiOperation("短信发送接口")
|
||||||
|
public R sendSms(@RequestPart String phone) {
|
||||||
|
iSmsService.sendSmsOne(phone);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("validationCode")
|
||||||
|
@ApiOperation("验证码验证")
|
||||||
|
public R<Boolean> validationCode(@RequestPart String phone, @RequestPart String code) {
|
||||||
|
System.out.println("phone = "+phone + " sms code = "+code);
|
||||||
|
return R.ok(iSmsService.validationCode(phone, code));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.ruoyi.web.core.config.SMSUtils;
|
import com.ruoyi.system.service.ISmsService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -36,16 +36,16 @@ import io.swagger.annotations.ApiOperation;
|
||||||
public class TestController extends BaseController
|
public class TestController extends BaseController
|
||||||
{
|
{
|
||||||
@Autowired
|
@Autowired
|
||||||
private SMSUtils smsUtils;
|
private ISmsService iSmsService;
|
||||||
|
|
||||||
@GetMapping("sms")
|
@GetMapping("sms")
|
||||||
@ApiOperation("短信测试接口")
|
@ApiOperation("短信测试接口")
|
||||||
public Object sendSMS() {
|
public R sendSMS() {
|
||||||
|
String phone = "17612400322";
|
||||||
smsUtils.sendSMS("17612400322", "6752");
|
iSmsService.sendSmsOne(phone);
|
||||||
|
return R.ok();
|
||||||
return "sendSMS OK!";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
|
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
|
||||||
{
|
{
|
||||||
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
|
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
package com.ruoyi.web.core.config;
|
|
||||||
|
|
||||||
import com.ruoyi.framework.config.properties.TencentCloudProperties;
|
|
||||||
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 org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class SMSUtils {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TencentCloudProperties tencentCloudProperties;
|
|
||||||
|
|
||||||
public void sendSMS(String phone, String code) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
/* 必要步骤:
|
|
||||||
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
|
|
||||||
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
|
|
||||||
* 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
|
|
||||||
* 以免泄露密钥对危及你的财产安全。
|
|
||||||
* CAM密匙查询获取: https://console.cloud.tencent.com/cam/capi
|
|
||||||
*/
|
|
||||||
Credential cred = new Credential(tencentCloudProperties.getSecretId(),
|
|
||||||
tencentCloudProperties.getSecretKey());
|
|
||||||
|
|
||||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
||||||
HttpProfile httpProfile = new HttpProfile();
|
|
||||||
|
|
||||||
// httpProfile.setReqMethod("POST"); // 默认使用POST
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SDK会自动指定域名。通常是不需要特地指定域名的,但是如果你访问的是金融区的服务
|
|
||||||
* 则必须手动指定域名,例如sms的上海金融区域名: sms.ap-shanghai-fsi.tencentcloudapi.com
|
|
||||||
*/
|
|
||||||
httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
|
||||||
|
|
||||||
// 实例化一个client选项
|
|
||||||
ClientProfile clientProfile = new ClientProfile();
|
|
||||||
clientProfile.setHttpProfile(httpProfile);
|
|
||||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
|
||||||
SmsClient client = new SmsClient(cred, "ap-nanjing", clientProfile);
|
|
||||||
|
|
||||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
|
||||||
SendSmsRequest req = new SendSmsRequest();
|
|
||||||
String[] phoneNumberSet1 = {
|
|
||||||
"+86" + phone
|
|
||||||
}; //电话号码
|
|
||||||
req.setPhoneNumberSet(phoneNumberSet1);
|
|
||||||
req.setSmsSdkAppId(tencentCloudProperties.getSmsSdkAppId()); // 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId
|
|
||||||
req.setSignName(tencentCloudProperties.getSignName()); // 签名
|
|
||||||
req.setTemplateId(tencentCloudProperties.getTemplateId()); // 模板id:必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看
|
|
||||||
|
|
||||||
/* 模板参数(自定义占位变量): 若无模板参数,则设置为空 */
|
|
||||||
String[] templateParamSet1 = {
|
|
||||||
code
|
|
||||||
};
|
|
||||||
req.setTemplateParamSet(templateParamSet1);
|
|
||||||
|
|
||||||
// 返回的resp是一个SendSmsResponse的实例,与请求对象对应
|
|
||||||
SendSmsResponse resp = client.SendSms(req);
|
|
||||||
// 输出json格式的字符串回包
|
|
||||||
// System.out.println(SendSmsResponse.toJsonString(resp));
|
|
||||||
}
|
|
||||||
catch (TencentCloudSDKException e) {
|
|
||||||
System.out.println(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -135,3 +135,5 @@ tencent:
|
||||||
signName: 优势管家
|
signName: 优势管家
|
||||||
templateId: 2200612
|
templateId: 2200612
|
||||||
smsSdkAppId: 1400921153
|
smsSdkAppId: 1400921153
|
||||||
|
region: ap-beijing
|
||||||
|
smsUrl: sms.tencentcloudapi.com
|
|
@ -119,6 +119,15 @@
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.ruoyi.common.config;
|
||||||
|
|
||||||
|
import com.tencentcloudapi.common.Credential;
|
||||||
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
public class TencentCloudProperties {
|
||||||
|
|
||||||
|
@Value("${tencent.cloud.secretId}")
|
||||||
|
private String secretId;
|
||||||
|
@Value("${tencent.cloud.secretKey}")
|
||||||
|
private String secretKey;
|
||||||
|
@Value("${tencent.cloud.signName}")
|
||||||
|
private String signName;
|
||||||
|
@Value("${tencent.cloud.templateId}")
|
||||||
|
private String templateId;
|
||||||
|
@Value("${tencent.cloud.smsSdkAppId}")
|
||||||
|
private String smsSdkAppId;
|
||||||
|
@Value("${tencent.cloud.region}")
|
||||||
|
private String region;
|
||||||
|
@Value("${tencent.cloud.smsUrl}")
|
||||||
|
private String smsUrl;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SmsClient smsClient(){
|
||||||
|
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
|
||||||
|
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
|
||||||
|
Credential cred = new Credential(secretId, secretKey);
|
||||||
|
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint(smsUrl);
|
||||||
|
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
//实例化 SMS 的 client 对象
|
||||||
|
return new SmsClient(cred, region, clientProfile);
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,16 +59,6 @@
|
||||||
<artifactId>ruoyi-system</artifactId>
|
<artifactId>ruoyi-system</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.tencentcloudapi</groupId>
|
|
||||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,22 +0,0 @@
|
||||||
package com.ruoyi.framework.config.properties;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Configuration
|
|
||||||
public class TencentCloudProperties {
|
|
||||||
|
|
||||||
@Value("${tencent.cloud.secretId}")
|
|
||||||
private String secretId;
|
|
||||||
@Value("${tencent.cloud.secretKey}")
|
|
||||||
private String secretKey;
|
|
||||||
@Value("${tencent.cloud.signName}")
|
|
||||||
private String signName;
|
|
||||||
@Value("${tencent.cloud.templateId}")
|
|
||||||
private String templateId;
|
|
||||||
@Value("${tencent.cloud.smsSdkAppId}")
|
|
||||||
private String smsSdkAppId;
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.ruoyi.system.service;
|
||||||
|
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
|
||||||
|
public interface ISmsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信的验证码
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String generateCode();
|
||||||
|
/**
|
||||||
|
* 发送短信的验证码
|
||||||
|
* @param phoneNumber
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String sendSms(String[] phoneNumber, String[] params) throws TencentCloudSDKException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证验证码
|
||||||
|
* @param phone
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean validationCode(String phone, String code);
|
||||||
|
|
||||||
|
void sendSmsOne(String phone);
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
package com.ruoyi.system.service;
|
|
||||||
|
|
||||||
public interface SmsService {
|
|
||||||
public void sendVerificationCode(String phoneNumber);
|
|
||||||
}
|
|
|
@ -1,39 +1,82 @@
|
||||||
package com.ruoyi.system.service.impl;
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
import com.ruoyi.system.service.SmsService;
|
import com.ruoyi.common.config.TencentCloudProperties;
|
||||||
|
import com.ruoyi.system.service.ISmsService;
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SmsServiceImpl implements SmsService {
|
public class SmsServiceImpl implements ISmsService {
|
||||||
|
|
||||||
// // 假设的第三方短信服务API
|
/**
|
||||||
// private SmsApi smsApi;
|
* 短信验证码长度
|
||||||
|
*/
|
||||||
|
private final Integer LENGTH = 6;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TencentCloudProperties tencentCloudProperties;
|
||||||
|
/**
|
||||||
|
* redis 缓存
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendVerificationCode(String phoneNumber) {
|
public String sendSms(String[] phoneNumber, String[] params) throws TencentCloudSDKException {
|
||||||
int verificationCode = generateVerificationCode();
|
SendSmsRequest req = new SendSmsRequest();
|
||||||
String message = "您的验证码是:" + verificationCode + ",请在5分钟内输入。";
|
req.setSignName(tencentCloudProperties.getSignName());
|
||||||
|
req.setSmsSdkAppId(tencentCloudProperties.getSmsSdkAppId());
|
||||||
// 调用第三方短信服务API发送短信
|
req.setTemplateId(tencentCloudProperties.getTemplateId());
|
||||||
// smsApi.sendSms(phoneNumber, message);
|
/* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
|
||||||
|
* 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 */
|
||||||
// 在这里,你可以将验证码保存到会话或数据库中,用于验证
|
req.setPhoneNumberSet(phoneNumber);
|
||||||
|
req.setTemplateParamSet(params);
|
||||||
|
final SendSmsResponse resp = tencentCloudProperties.smsClient().SendSms(req);
|
||||||
|
// 输出json格式的字符串回包
|
||||||
|
System.out.println(SendSmsResponse.toJsonString(resp));
|
||||||
|
return resp.getSendStatusSet()[0].getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成随机验证码的方法
|
/**
|
||||||
private int generateVerificationCode() {
|
* 生成随机的验证码
|
||||||
Random random = new Random();
|
*
|
||||||
int verificationCode = random.nextInt(899999) + 100000; // 生成六位验证码
|
* @return
|
||||||
return verificationCode;
|
*/
|
||||||
|
public String generateCode() {
|
||||||
|
return RandomStringUtils.randomNumeric(LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean validationCode(String phone, String code) {
|
||||||
|
final String data = (String) redisTemplate.opsForValue().get(phone);
|
||||||
|
if (code.equals(data)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
@Override
|
||||||
// 假设已经实现了SmsApi接口,并且有一个实例smsApi
|
public void sendSmsOne(String phone) {
|
||||||
SmsService smsService = new SmsServiceImpl();
|
try {
|
||||||
smsService.sendVerificationCode("13812345678");
|
String code = generateCode();
|
||||||
|
String[] phoneNumber = new String[]{phone};
|
||||||
|
String[] params = new String[]{code};
|
||||||
|
String status = sendSms(phoneNumber, params);
|
||||||
|
System.out.println(status + "sms code = "+code);
|
||||||
|
if("Ok".equals(status)){
|
||||||
|
redisTemplate.opsForValue().set(phone, code);
|
||||||
|
}
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue