SpringBoot集成騰訊云短信服務(wù)全攻略
騰訊云短信核心概念
在開始前,需要了解幾個(gè)核心概念:
| 概念 | 說明 | 備注 |
|---|---|---|
| 短信簽名 | 附加在短信內(nèi)容前的標(biāo)識(shí),用于標(biāo)識(shí)發(fā)送方身份,如公司或產(chǎn)品名稱。 | 發(fā)送國內(nèi)短信必須使用已審核通過的簽名。 |
| 短信模板 | 預(yù)設(shè)的短信內(nèi)容,包含可變參數(shù)的占位符(如{1})。 | 模板需審核。發(fā)送時(shí)將占位符替換為具體值。 |
| SDKAppID & AppKey | 代表短信應(yīng)用的唯一憑證,用于鑒權(quán)。 | 在短信控制臺(tái) > 應(yīng)用管理中查看。 |
| SecretId & SecretKey | 騰訊云API訪問密鑰,代表你的云賬戶權(quán)限,部分SDK或API方式會(huì)用到。 | 在訪問管理[CAM]控制臺(tái)創(chuàng)建和管理。 |
實(shí)施前準(zhǔn)備
- 開通服務(wù)與創(chuàng)建應(yīng)用
- 在騰訊云短信控制臺(tái)開通服務(wù)。
- 在“應(yīng)用管理”中創(chuàng)建一個(gè)應(yīng)用,獲得 SDKAppID,并生成對應(yīng)的 AppKey(如果使用舊版SDK)。
- 創(chuàng)建簽名與模板
- 在控制臺(tái)根據(jù)用途(自用/他用)和類型(APP、網(wǎng)站等)申請短信簽名。
- 根據(jù)短信類型(驗(yàn)證碼、通知、營銷)創(chuàng)建正文模板,使用
{數(shù)字}格式定義變量,例如:您的驗(yàn)證碼是{1},有效期{2}分鐘。。 - 等待審核通過后,記錄簽名內(nèi)容和模板ID。
Spring Boot集成步驟
1. 引入官方SDK依賴
騰訊云為Java提供了tencentcloud-sdk-java。在pom.xml中添加依賴(請檢查Maven倉庫使用最新版本):
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.XXX</version> <!-- 請?zhí)鎿Q為最新版本 -->
<scope>compile</scope>
</dependency>
該SDK封裝了所有短信API,推薦使用。
2. 配置安全憑證
將憑證配置在application.yml中,切勿提交至代碼倉庫。
tencent:
sms:
secret-id: your-secret-id # 替換為你的SecretId
secret-key: your-secret-key # 替換為你的SecretKey
sdk-app-id: 1400000000 # 替換為你的SDKAppID
sign-name: 你的簽名內(nèi)容 # 替換為審核通過的簽名內(nèi)容
template-id: 1234567 # 替換為你常用的默認(rèn)模板ID
在配置類中讀取這些值:
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "tencent.sms")
@Data
public class TencentSmsProperties {
private String secretId;
private String secretKey;
private String sdkAppId;
private String signName;
private String templateId;
}
3. 創(chuàng)建短信發(fā)送服務(wù)
創(chuàng)建一個(gè)服務(wù)類來封裝發(fā)送邏輯。
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.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class TencentSmsService {
private final TencentSmsProperties smsProperties;
/**
* 發(fā)送短信驗(yàn)證碼
*
* @param phoneNumber 目標(biāo)手機(jī)號(hào)(帶區(qū)號(hào),如"+8613712345678")
* @param templateId 模板ID(可選,不填則使用配置的默認(rèn)模板ID)
* @param templateParams 模板參數(shù)列表,按順序替換模板中的變量{citation:6}
* @return 發(fā)送是否成功
*/
public boolean sendSms(String phoneNumber, String templateId, String[] templateParams) {
try {
// 1. 實(shí)例化認(rèn)證對象,傳入SecretId和SecretKey[citation:10]
Credential cred = new Credential(smsProperties.getSecretId(), smsProperties.getSecretKey());
// 2. 配置HTTP和客戶端Profile
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("sms.tencentcloudapi.com"); // 短信API端點(diǎn)
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 3. 實(shí)例化SmsClient
SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile); // 地域根據(jù)控制臺(tái)指引選擇
// 4. 構(gòu)造請求對象并填充參數(shù)
SendSmsRequest req = new SendSmsRequest();
req.setSmsSdkAppId(smsProperties.getSdkAppId()); // 設(shè)置應(yīng)用ID[citation:2]
req.setSignName(smsProperties.getSignName()); // 設(shè)置簽名[citation:2]
req.setTemplateId(templateId != null ? templateId : smsProperties.getTemplateId()); // 設(shè)置模板ID
req.setPhoneNumberSet(new String[]{phoneNumber}); // 設(shè)置手機(jī)號(hào),支持批量
req.setTemplateParamSet(templateParams); // 設(shè)置模板參數(shù)
// 5. 發(fā)起請求并處理響應(yīng)
SendSmsResponse resp = client.SendSms(req);
SendStatus status = resp.getSendStatusSet()[0]; // 取第一個(gè)號(hào)碼的發(fā)送狀態(tài)
log.info("短信發(fā)送請求ID:{},狀態(tài):{},狀態(tài)碼:{}", resp.getRequestId(), status.getMessage(), status.getCode());
// 6. 判斷發(fā)送結(jié)果(通常以"Ok"表示成功,請根據(jù)實(shí)際響應(yīng)判斷)
return "Ok".equalsIgnoreCase(status.getCode());
} catch (TencentCloudSDKException e) {
log.error("騰訊云短信SDK調(diào)用失敗,錯(cuò)誤信息:{}", e.toString(), e);
return false;
}
}
/**
* 簡化方法:發(fā)送固定模板的短信(如驗(yàn)證碼)
*
* @param phoneNumber 目標(biāo)手機(jī)號(hào)
* @param code 驗(yàn)證碼
* @return 發(fā)送是否成功
*/
public boolean sendVerificationCode(String phoneNumber, String code) {
// 假設(shè)你的驗(yàn)證碼模板內(nèi)容為:您的驗(yàn)證碼是{1},有效期{2}分鐘。
String[] templateParams = {code, "5"}; // 驗(yàn)證碼和有效期
return sendSms(phoneNumber, null, templateParams); // 使用配置中的默認(rèn)模板ID
}
}
核心說明:
- 憑證安全:
SecretId和SecretKey代表賬戶所有權(quán),務(wù)必保密。 - 地域選擇:實(shí)例化
SmsClient時(shí)的地域參數(shù)(如ap-guangzhou)需與短信控制臺(tái)應(yīng)用所在地域一致。 - 錯(cuò)誤處理:生產(chǎn)環(huán)境需更完善的錯(cuò)誤處理(如重試、熔斷)和狀態(tài)監(jiān)控。
4. 創(chuàng)建控制器提供API接口
創(chuàng)建一個(gè)簡單的REST API接口,供前端或其他服務(wù)調(diào)用。
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/sms")
@RequiredArgsConstructor
public class SmsController {
private final TencentSmsService smsService;
@PostMapping("/send-code")
public ApiResponse sendVerificationCode(@RequestParam String phoneNumber) {
// 1. 生成隨機(jī)驗(yàn)證碼(示例)
String code = String.valueOf((int)((Math.random() * 9 + 1) * 100000));
// 2. 發(fā)送短信
boolean isSuccess = smsService.sendVerificationCode(phoneNumber, code);
// 3. 此處應(yīng)將驗(yàn)證碼與手機(jī)號(hào)關(guān)聯(lián)存儲(chǔ)到Redis或Session,并設(shè)置過期時(shí)間,用于后續(xù)校驗(yàn)[citation:6]
// redisTemplate.opsForValue().set("SMS_CODE:" + phoneNumber, code, 5, TimeUnit.MINUTES);
if (isSuccess) {
return ApiResponse.success("短信發(fā)送成功");
} else {
return ApiResponse.fail("短信發(fā)送失敗,請稍后重試");
}
}
// 簡單的響應(yīng)封裝類
@Data
public static class ApiResponse {
private boolean success;
private String message;
private Object data;
public static ApiResponse success(String message) {
ApiResponse response = new ApiResponse();
response.setSuccess(true);
response.setMessage(message);
return response;
}
public static ApiResponse fail(String message) {
ApiResponse response = new ApiResponse();
response.setSuccess(false);
response.setMessage(message);
return response;
}
}
}
核心流程與最佳實(shí)踐
將上面的步驟整合后,完整的短信發(fā)送流程如下:
為了確保服務(wù)安全和穩(wěn)定,請遵循以下實(shí)踐:
- 頻率限制:在控制臺(tái)或代碼中,對同一手機(jī)號(hào)設(shè)置發(fā)送頻率和數(shù)量限制(如30秒1條、1天10條),防止短信轟炸。
- 安全存儲(chǔ):使用Redis等緩存驗(yàn)證碼,并設(shè)置合理的過期時(shí)間(如5分鐘),切勿返回給前端。
- 監(jiān)控與告警:關(guān)注發(fā)送成功率,配置云監(jiān)控告警,對于發(fā)送失敗或頻率異常及時(shí)處理。
- 事務(wù)與冪等:關(guān)鍵業(yè)務(wù)(如支付)的短信發(fā)送,應(yīng)考慮與業(yè)務(wù)邏輯的事務(wù)一致性,并對發(fā)送請求做冪等處理。
總結(jié)
在Spring Boot中集成騰訊云短信服務(wù),核心是安全配置、服務(wù)封裝和流程管控。
| 環(huán)節(jié) | 關(guān)鍵點(diǎn) | 常見問題 |
|---|---|---|
| 前期準(zhǔn)備 | 企業(yè)認(rèn)證、簽名/模板審核、獲取憑證 | 個(gè)人用戶無法使用營銷短信;模板變量格式錯(cuò)誤。 |
| 開發(fā)集成 | 使用官方Java SDK、保護(hù)SecretKey、合理封裝服務(wù)類。 | 地域配置錯(cuò)誤;SDK版本過舊。 |
| 生產(chǎn)保障 | 設(shè)置發(fā)送頻率限制、驗(yàn)證碼安全存儲(chǔ)與校驗(yàn)、監(jiān)控告警。 | 短信被刷;驗(yàn)證碼被爆破;服務(wù)不可用無感知。 |
以上就是SpringBoot集成騰訊云短信服務(wù)全攻略的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot集成騰訊云短信的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java實(shí)現(xiàn)經(jīng)典游戲泡泡堂的示例代碼
這篇文章將利用Java制作經(jīng)典游戲——泡泡堂,游戲設(shè)計(jì)為雙人pk積分賽模式,在這個(gè)模式里面,玩家只要率先達(dá)到一定分?jǐn)?shù)既可以贏得比賽。感興趣的可以了解一下2022-04-04
Spring Boot2發(fā)布調(diào)用REST服務(wù)實(shí)現(xiàn)方法
這篇文章主要介紹了Spring Boot2發(fā)布調(diào)用REST服務(wù)實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
java中catalina.home與catalina.base區(qū)別點(diǎn)整理
在本篇文章里小編給大家整理的是關(guān)于java項(xiàng)目中catalina.home與catalina.base區(qū)別點(diǎn),需要的朋友們可以學(xué)習(xí)下。2020-02-02
java得到某年某周的第一天實(shí)現(xiàn)思路及代碼
某年某周的第一天,此功能如何使用java編程得到呢?既然有了問題就有解決方法,感興趣的朋友可以了解下本文,或許會(huì)給你帶來意想不到的收獲哦2013-01-01
Java實(shí)現(xiàn)對象復(fù)制的方法實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)對象復(fù)制的方法實(shí)例,深復(fù)制:復(fù)制出來的對象中的變量(包括基本類型和字符串)和原來的對象的值都相同,引用對象也會(huì)指向復(fù)制出來的對象,需要的朋友可以參考下2023-08-08
SpringBoot http請求注解@RestController原理解析
這篇文章主要介紹了SpringBoot http請求注解@RestController原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01

