第三方API——Spring Boot 集成阿里云短信發送功能

目錄

一. 創建阿里云OSS服務并獲取密鑰,開通短信服務

1.1 注冊阿里云服務器

?1.2 開通短信服務

1.3 創建對象存儲OSS服務

1.4 RAM用戶授權短信權限

1.5 新增用戶并授權用戶短信權限

1.6 獲取?AccessKey ID 和 AccessKey Secret

二. 創建項目集成短信發送

2.1 引入依賴

2.2 修改 yml 文件

2.3 創建阿里云短信配置類

2.4 編寫 SmsService? 短信發送模板業務類

2.5 在業務中調用短信發送的方法


一. 創建阿里云OSS服務并獲取密鑰,開通短信服務

1.1 注冊阿里云服務器

點擊鏈接,直接選擇一種登錄方式注冊登陸即可。

阿里云登錄 - 歡迎登錄阿里云,安全穩定的云計算服務平臺

?1.2 開通短信服務

搜索短信服務,點擊跳轉然后有免費開通。

如下頁面,簡單過一遍"快速學習與測試"

?走完上面的流程,我們點擊"國內消息",然后如右側頁面所示,需要去申請"資質",只要是項目集成都需要申請"資質",資質申請審核完畢;到簽名頁面添加簽名,簽名會需要使用到申請的資質,簽名創建完畢后,添加我們的短信模板,自行選擇即可,也可以自定義模板。

創建完畢之后,一定要把"簽名","短信模板Code碼"記下來,一會在代碼中會用到

這里以我的為例,簽名是"aliyunSM666"。

短信模板Code為"SMS_481015005"

?

1.3 創建對象存儲OSS服務

左上角搜索輸入"對象存儲",即可找到對象存儲OSS服務,點擊跳轉。

?然后來到如下頁面,點擊 Bucket——>創建Bucket 一步步操作即可。

這里需要記一個點,如果創建的地域是北京,那么下面在配置 yml 文件時,aliyun.regionId 的值就是 cn-beijing;如果是杭州,就是 cn-hangzhou;如果是上海,就是cn-shanghai。

1.4 RAM用戶授權短信權限

創建完畢 Bucket 完畢后,點擊創建的 Bucket 進入詳情頁。

然后前往RAM控制臺

1.5 新增用戶并授權用戶短信權限

來到RAM控制臺,先新增一名用戶,然后點擊添加權限

在權限策略中輸入短信即可搜索到,直接授權給用戶即可。?

如果之前已經創建過用戶,直接授權即可,也可以像下圖所示,到授權頁面選擇指定用戶授權不能

1.6 獲取?AccessKey ID 和 AccessKey Secret

點擊右上角用戶頭像

跳轉到 AccessKey 詳情頁,如果沒有則新建一個即可,

注意!!!AssessKey Secret 新建后不會再展示,首次新建請保存,如果遺忘只需禁用現有的AssessKey,再新建一個即可。

二. 創建項目集成短信發送

2.1 引入依賴
    <!-- 阿里云核心 SDK --><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.16</version></dependency><!-- 短信服務 SDK --><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>2.1.0</version></dependency><!-- OSS SDK --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version></dependency>

2.2 修改 yml 文件

如下圖所示,修改項目的 yml 文件,在 yml 文件中添加 aliyun 配置。

assessKeyId 就是上面第一步提到的 AccessKey ID;

accessKeySecret 就是上面提到的 AccessKey Secret;

regionId 激素hi上面提到的 cn-shanghai;根據自己創建的 Bucket 區域而定。

2.3 創建阿里云短信配置類

在下面配置類中,首先獲取 yml 配置文件中設置的值,然后編寫返回實例的方法并將值賦值給新建實例。

然后,使用短信客戶端實例調用 API 接口發送短信,這里寫為一個方法,傳遞手機號,簽名,短信模板Code值,然后再其他業務類型,注入此配置類的實例,調用 sendSms 方法,根據業務需求傳遞不同的短信Code發送不同的短信。

@Configuration
public class AliyunSmsConfig {// 1.阿里云賬號的accessKeyId@Value("${aliyun.assessKeyId}")private String accessKeyId;// 2.阿里云賬號的accessKeySecret@Value("${aliyun.assessKeySecret}")private String accessKeySecret;// 3.阿里云賬號的regionId@Value("${aliyun.regionId}")private String regionId;// 創建并初始化阿里云短信服務的客戶端實例@Beanpublic IAcsClient acsClient() {DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);return new DefaultAcsClient(profile);}// 發送短信的核心邏輯,通過 IAcsClient 調用阿里云短信服務 APIpublic SendSmsResponse sendSms(String phoneNumber, String signName, String templateCode, String templateParam) throws Exception {IAcsClient client = acsClient();SendSmsRequest request = new SendSmsRequest();request.setPhoneNumbers(phoneNumber);request.setSignName(signName);request.setTemplateCode(templateCode);request.setTemplateParam(templateParam);return client.getAcsResponse(request);}
}

2.4 編寫 SmsService? 短信發送模板業務類

在上面,我們已經定義好了發送短信的方法,按道理來說,直接 @Autowired 注入 配置的 Bean 實例就可以了,但是我們觀察上方方法,其實還不夠簡潔,因為 sendSms 方法中,只有 phone 手機號一個參數是需要用戶傳遞的,其他的參數是不需要的。

因此,我們最好再進行一層抽取,將每一種發送短信驗證碼的方法寫成一個 Service 業務類,這樣一來其他類當要發送短信的時候,直接調用封裝好的 Service 中的方法即可,優化了原本的業務類代碼。

如下代碼所示,

定義一個發送登錄驗證碼的方法 "sendLoginVerificationCode",還可以定義發送修改密碼的驗證碼 "sendUpdatePasswordVerificationCode",還可以定義付錢的驗證碼方法 "sendPayMoneyVerificationCode"。

當然啦,這里只是舉個例子,實際業務項目中,需要發送的短信驗證碼肯定也是多種多樣的,可以定義多個方法,也可以定義一個通用方法,都是可以的,小編這里就采用這種常用寫法啦。

@Service
@Slf4j
public class SmsService {@Autowiredprivate AliyunSmsConfig aliyunSmsConfig;public boolean sendLoginVerificationCode(String phoneNumber, String code) {try {SendSmsResponse response = aliyunSmsConfig.sendSms(phoneNumber,"aliyunSMS666","SMS_481015005","{\"code\":\"" + code + "\"}");log.info(response.getCode());return "OK".equals(response.getCode());} catch (Exception e) {e.printStackTrace();return false;}}public boolean sendUpdatePasswordVerificationCode(String phoneNumber, String code) {try {SendSmsResponse response = aliyunSmsConfig.sendSms(phoneNumber,"aliyunSMS666","SMS_481015005","{\"code\":\"" + code + "\"}");log.info(response.getCode());return "OK".equals(response.getCode());} catch (Exception e) {e.printStackTrace();return false;}}public boolean sendPayMoneyVerificationCode(String phoneNumber, String code) {......}
}

2.5 在業務中調用短信發送的方法

上面的工作都做完之后,我們就可以進入到真正的業務層了,如下代碼,其實非常簡單,這里小編定義了五個方法,其實這里的 sendCode 方法是可以不用要的,畢竟代碼不多,也可以直接將代碼寫入到 login 登陸方法中。

"selectByUsername" 查詢用戶方法;

"sendCode"發送短信方法;

"login" 登陸方法;

"createUser" 創建新用戶方法;

"generateTokenByUid" 生成用戶 token 方法;

邏輯很簡單,都有注釋,大家一步一步看即可。

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {// 添加類頂部聲明private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);@Autowiredprivate UserMapper userMapper;@Autowiredprivate SmsService smsService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;// 方法一: 根據用戶名查詢用戶是否已存在@Overridepublic Boolean selectByUsername(String username) {return !userMapper.selectByUserName(username).isEmpty();}/* 方法二: 發送短信方法 */public Boolean sendCode(String phone) {// 1. 生成6位隨機數作為驗證碼SecureRandom secureRandom = new SecureRandom();String code = String.valueOf(100000 + secureRandom.nextInt(900000));// 2. 將驗證碼存入RedisstringRedisTemplate.opsForValue().set(phone,String.valueOf(code),5, java.util.concurrent.TimeUnit.MINUTES);// 3. 發送驗證碼try {logger.info("準備發送驗證碼,手機號:{},驗證碼:{}",phone,code);return smsService.sendLoginVerificationCode(phone, code);} catch (Exception e) {logger.error("短信發送失敗,手機號:{},錯誤信息:{}", phone, e.getMessage(), e);return false;}}/* 方法三:用戶登錄+注冊接口綜合方法 */public Result<Boolean> login(LoginDto loginDto, HttpServletRequest request, HttpServletResponse response){Result<Boolean> result = new Result<>();// 1. 登陸方式一: 手機號+短信登錄if (loginDto.getPhone() != null && loginDto.getCode() != null){List<User> users = userMapper.selectUserByPhone(loginDto.getPhone());if (users.isEmpty()){createUser(loginDto);}String code = stringRedisTemplate.opsForValue().get(loginDto.getPhone());if (code != null && code.equals(loginDto.getCode())){generateTokenByUid(users.get(0).getId(), request, response);result.setCode(200);result.setData(true);result.setMsg("success");}else{result.setCode(999);result.setMsg("驗證碼錯誤");result.setData(false);}return result;}// 2. 登陸方式二:手機號+密碼登錄else if (loginDto.getUsername() != null && loginDto.getPassword() != null){User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));if (user != null && MD5Utils.md5HashWithSalt(loginDto.getPassword(), user.getSalt()).equals(user.getPassword())){generateTokenByUid(user.getId(), request, response);result.setCode(200);result.setData(true);result.setMsg("success");}else{result.setCode(999);result.setMsg("密碼錯誤");result.setData(false);}result.setCode(999);result.setMsg("未知錯誤");result.setData(false);return result;}// 3. 登陸方式三:用戶名+密碼登錄else if (loginDto.getUsername() != null || loginDto.getPassword() != null) {User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));if (user != null && MD5Utils.md5HashWithSalt(loginDto.getPassword(), user.getSalt()).equals(user.getPassword())){generateTokenByUid(user.getId(), request, response);result.setCode(200);result.setData(true);result.setMsg("success");}else if (user == null && loginDto.getPassword() != null && loginDto.getPassword2() != null && loginDto.getPassword().equals(loginDto.getPassword2())){User newUser = createUser(loginDto);generateTokenByUid(newUser.getId(), request, response);}else {result.setCode(999);result.setMsg("密碼錯誤");result.setData(false);}}result.setCode(999);result.setMsg("未知錯誤");result.setData(false);return result;}/* 方法四:創建新用戶方法 */public User createUser(LoginDto loginDto){User user = new User();user.setPhone(loginDto.getPhone());user.setStatus(0);if (loginDto.getUsername() != null){user.setUsername(loginDto.getUsername());// 生成隨機密碼鹽值字符串String salt = UUID.randomUUID().toString().replaceAll("-", "");user.setSalt(salt);user.setPassword(MD5Utils.md5HashWithSalt(loginDto.getPassword(), salt));}user.setAvatar("https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/5a9f48118166308daba8b6da7e466aab.jpg");user.setCreated(LocalDateTime.now());userMapper.insert(user);return user;}/* 方法五:生成 Token 方法*/public void generateTokenByUid(Long uid, HttpServletRequest request, HttpServletResponse response){String token = JwtUtils.generateToken(uid);response.setHeader("Authorization", token);response.setHeader("Access-control-Expose-Headers", "Authorization");}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77470.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77470.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77470.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

b站PC網頁版視頻播放頁油猴小插件制作

文章目錄 前言需求分析實施觀察頁面起始渲染編碼效果展示 總結 前言 新手上路,歡迎指導 需求分析 想要一個簡約干凈的界面,需要去除推薦欄和廣告部分. 想要自由調節視頻播放速率,需要在視頻控制欄加一個輸入框控制視頻倍速 實施 觀察頁面起始渲染 因為要使用MutationObse…

暢游Diffusion數字人(27):解讀字節跳動提出主題定制視頻生成技術Phantom

暢游Diffusion數字人(0):專欄文章導航 前言:主題定制視頻生成,特別是zero-shot主題定制視頻生成,一直是當前領域的一個難點,之前的方法效果很差。字節跳動提出了一個技術主題定制視頻生成技術Phantom,效果相比于之前的技術進步非常顯著。這篇博客詳細解讀一下這一工作。 …

ESP8266簡單介紹

ESP8266模塊圖如下 ESP8266的工作模式有三種 ESP8266支持STA、AP、STAAP三種工作模式 ①STA模式 &#xff08;ESP充當設備與路由器相連&#xff09; ②AP模式 &#xff08;ESP充當路由器&#xff09; ③APSTA&#xff08;上述兩種模式兼具&#xff09; AT指令介紹 使用安…

DeepSeek-R3、GPT-4o 與 Claude-3.5-Sonnet 全面對比:性能、應用場景與技術解析

隨著大模型技術的迅猛發展&#xff0c;國產模型正逐漸嶄露頭角&#xff0c;尤其是DeepSeek-R3的發布&#xff0c;更是在AI技術社區中引起廣泛關注。而與此同時&#xff0c;國際領先的GPT-4o和Claude-3.5-Sonnet也在不斷迭代升級&#xff0c;持續刷新業界對AI能力的認知。下文將…

城市街拍暗色電影膠片風格Lr調色教程,手機濾鏡PS+Lightroom預設下載!

調色介紹 城市街拍暗色電影膠片風格 Lr 調色&#xff0c;是借助 Adobe Lightroom 軟件&#xff0c;為城市街拍的人像或場景照片賦予獨特視覺風格的后期處理方式。旨在模擬電影膠片質感&#xff0c;營造出充滿故事感與藝術感的暗色氛圍&#xff0c;讓照片仿佛截取于某部充滿張力…

數字后端設計 (一):數字電路設計的「前后端」到底是什么?

—— 想象你在做一道菜——前端設計是寫菜譜&#xff0c;后端設計是進廚房真正炒菜。這篇文章幫你搞懂「芯片設計」里這兩個階段到底在干嘛。 1. 前端設計——寫一份「理想化」的菜譜 任務&#xff1a;用代碼描述芯片的功能。例子&#xff1a;你要做一個自動計算“112”的芯片…

網站301搬家后谷歌一直不收錄新頁面怎么辦?

當網站因更換域名或架構調整啟用301重定向后&#xff0c;許多站長發現谷歌遲遲不收錄新頁面&#xff0c;甚至流量大幅下滑。 例如&#xff0c;301跳轉設置錯誤可能導致權重傳遞失效&#xff0c;而新站內容與原站高度重復則可能被谷歌判定為“低價值頁面”。 即使技術層面無誤&a…

WiFi“管家”------hostapd的工作流程

目錄 1. 啟動與初始化 1.1 解析命令行參數 1.2 讀取配置文件 1.3 創建接口和 BSS 數據結構 1.4 初始化驅動程序 2. 認證和關聯處理 2.1 監聽認證請求 2.2 處理認證請求 2.3 處理關聯請求 3. 數據轉發 3.1 接收客戶端數據 3.2 轉發數據 4. 斷開連接處理 4.1 處理客…

YOLOv2 快速入門與核心概念:更快、更準的目標檢測利器

今天&#xff0c;我們就來聊聊 YOLO 系列的第二代—— YOLOv2&#xff0c;看看它是如何在速度的基礎上&#xff0c;進一步提升檢測精度的。 目標檢測的重要性&#xff1a;讓機器“看懂”世界 想象一下&#xff0c;自動駕駛汽車需要實時識別道路上的車輛、行人、交通標志&…

[蒼穹外賣 | 項目日記] 第三天

前言 實現了新增菜品接口實現了菜品分頁查詢接口實現了刪除菜品接口實現了根據id查詢菜品接口實現了修改菜品接口 今日收獲&#xff1a; 今日的這幾個接口其實和之前寫的對員工的操作是一樣的&#xff0c;都是一整套Curd操作&#xff0c;所以今天在技術層面上并沒有…

Go語言入門到入土——三、處理并返回異常

Go語言入門到入土——三、處理并返回異常 文章目錄 Go語言入門到入土——三、處理并返回異常1. 在greetings.go中添加異常處理代碼2. 在hello.go中添加日志記錄代碼3. 運行 1. 在greetings.go中添加異常處理代碼 處理空輸入的異常&#xff0c;代碼如下&#xff1a; package g…

創維E900V20C-國科GK6323V100C-rtl8822cs-安卓9.0-短接強刷卡刷固件包

創維E900V20C&#xff0f;創維E900V20D-國科GK6323V100C-安卓9.0-強刷卡刷固件包 創維E900V20C 刷機說明&#xff1a; 1、用個老款4G&#xff0c;2.0的U盤&#xff0c;fat32&#xff0c;2048塊單分區格式化&#xff0c; 5個文件復制到根目錄&#xff0c;插盒子靠網口U口&…

視頻分析設備平臺EasyCVR安防視頻管理系統,打造電石生產智能視頻監控新體系

一、背景介紹 電石生產中的出爐工序是整個生產流程中最為繁重且危險的環節。在開堵爐眼的過程中&#xff0c;電石極易發生飛濺現象&#xff0c;尤其在進行吹氧操作時&#xff0c;人員灼傷的風險極高。鑒于此&#xff0c;該工序正逐步由傳統的人工操作模式向智能化方向轉變。然…

Verilog的整數除法

1、可變系數除法實現----利用除法的本質 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2025/04/15 13:45:39 // Design Name: // Module Name: divide_1 // Project Name: // Target Devices: // Tool Versions: // Description: // // Depe…

UniApp + Cursor + Devbox 全欄平臺開發教程:從0到完整項目打造

本文基于B站熱門教程《一口氣學會小程序 / App / H5開發:UniApp教程 + Cursor + Devbox》,https://www.bilibili.com/video/BV1W7QZYMEus/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=a1428945043b2df41c1896acb90d942a,進行全面擴展…

ESP32-idf學習(一)搭建環境和點燈

一、前言 先說一下查到的數據&#xff08;不保證準確&#xff09;&#xff1a; 1、連續四年Wi-Fi MCU全球市場份額第一&#xff0c;產品應用于智能家居、工業自動化、醫療健康等泛IoT領域?&#xff0c;2024 年營收突破 20 億元&#xff08;同比 40%&#xff09;&#xff0c;…

hooker frida版just_trust_me.js 2025升級 支持boringssl unpinning

曾幾何時&#xff0c;我翻版了 Xposed 的 just_trust_me.apk&#xff0c; just_trust_me.js 腳本仿佛是一張通行證&#xff0c;讓我們在 SSL Pinning 的高墻前輕松穿越。 但時代變了。BoringSSL、Cronet、靜態 inline hook、動態 verify callback……一切都變得更加隱蔽和棘手…

通信算法之269 : OFDM信號的循環自相關特性用于無人機圖傳信號識別

OFDM信號的循環自相關特性是其循環平穩性的核心體現,如下: [相關仿真代碼,聯系,提供] 一、循環自相關特性來源 ?循環前綴引入周期性? OFDM符號通過添加循環前綴(CP)形成符號周期結構,導致信號具有循環平穩性?26。每個符號的CP與尾部數據重復,在時延等于FFT長度(N…

vue3環境搭建、nodejs22.x安裝、yarn 1全局安裝、npm切換yarn 1、yarn 1 切換npm

vue3環境搭建 node.js 安裝 驗證nodejs是否安裝成功 # 檢測node.js 是否安裝成功----cmd命令提示符中執行 node -v npm -v 設置全局安裝包保存路徑、全局裝包緩存路徑 在node.js 安裝路徑下 創建 node_global 和 node_cache # 設置npm全局安裝包保存路徑&#xff08;新版本…

基于尚硅谷FreeRTOS視頻筆記——6—滴答時鐘—上下文切換

FreeRTOS滴答 FreeRTOS需要有一個時鐘參照&#xff0c;并且這個時鐘不會被輕易打斷&#xff0c;所以最好選擇systick 為什么需要時間參照 就是在高優先級任務進入阻塞態后&#xff0c;也可以理解為進入delay&#xff08;&#xff09;函數后&#xff0c;需要有一個時間參照&…