SpringBoot整合阿里云短信服务

news2024/11/20 9:39:13

文章目录

    • 1. 准备工作
    • 2. 添加依赖
    • 3. 配置阿里云短信服务
    • 4. 创建配置类
    • 5. 创建服务类
    • 6.自定义异常
    • 7.使用服务类发送短信
    • 8.测试短信

1. 准备工作

  • 注册阿里云账号:首先确保你有一个阿里云账号,并且已经开通了短信服务。
  • 获取AccessKey ID和AccessKey Secret:在阿里云控制台的安全管理页面创建AccessKey,这是访问阿里云API的凭证。
  • 申请短信签名和模板:在阿里云短信服务控制台申请短信签名和短信模板,签名用于标识发送者的身份,模板用于定义短信内容,需要审核通过才能使用。

在这里插入图片描述

2. 添加依赖

在Spring Boot项目的pom.xml文件中添加阿里云短信服务SDK的依赖。例如:

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.6.0</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>2.1.0</version>
</dependency>

3. 配置阿里云短信服务

application.ymlapplication.properties中配置AccessKey ID、AccessKey Secret以及其他可能需要的参数,例如:

sms:
  aliyun:
    accessKeyId: your-access-key-id
    accessKeySecret:  your-access-key-secret
    signName: ####
    # 是否开启短信服务
    pushSms: true
    templateCode: SMS_#########

4. 创建配置类

package com.example.demo.config.sms;

import com.aliyun.teaopenapi.models.*;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author xueyaoxuan
 */
@Data
@Component
@ConfigurationProperties(prefix = "sms.aliyun")
public class AliYunSmsConfig {

    private String accessKeyId;
    private String accessKeySecret;
    private String signName;
    private boolean isPushSms;

    /**
     * 使用AK&SK初始化账号Client
     *
     * @return Client
     * @throws Exception
     */
    public com.aliyun.dysmsapi20170525.Client createClient() throws Exception {
        Config config = new Config()
                // AccessKey ID
                .setAccessKeyId(this.getAccessKeyId())
                // AccessKey Secret
                .setAccessKeySecret(this.getAccessKeySecret());
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

}

5. 创建服务类

创建一个服务类来封装发送短信的逻辑

package com.example.demo.sms;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.example.demo.config.sms.AliYunSmsConfig;
import com.example.demo.config.ResultCode;
import com.example.demo.exception.base.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 阿里云短信服务实现
 * @author xueyaoxuan
 */
@Slf4j
@Component
public class AliYunSmsServiceImpl implements SmsService {

    @Autowired
    AliYunSmsServiceImpl (AliYunSmsConfig aliYunSmsConfig) {
        this.aliYunSmsConfig = aliYunSmsConfig;
    }

    private AliYunSmsConfig aliYunSmsConfig;

    @Override
    public void sendSms(List<String> mobiles, String message, String code) {
        SendSmsResponse sendSmsResponse = null;
        try{
            //调用阿里云api手机号上限1000
            if (mobiles.size()>1000){
                throw new BaseException(ResultCode.EM_SMS_MAX_LIMIT);
            }
            //检验手机号格式
            mobiles.forEach(mobile->{
                if (StrUtil.isAllEmpty(mobile)){
                    throw new BaseException(ResultCode.EM_SMS_INVALID_MOBILE);
                }
            });
            sendSmsResponse = sendALiYunSms(mobiles.stream().collect(Collectors.joining(",")),
                    message, code);
            log.info("阿里云短信服务响应:[{}]",JSON.toJSONString(sendSmsResponse));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送阿里云短信
     *
     * @param mobiles 手机号列表
     * @param message json格式的模板参数
     * @param code 阿里云短信模板code
     * @return
     * @throws Exception
     */
    private SendSmsResponse sendALiYunSms(String mobiles,String message,String code) throws Exception {

        //初始化Client对象
        Client client = aliYunSmsConfig.createClient();

        //构建请求参数
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(mobiles)
                .setSignName(aliYunSmsConfig.getSignName())
                .setTemplateCode(code)
                .setTemplateParam(message);
        //发送短信
        return client.sendSms(sendSmsRequest);

    }

}

6.自定义异常

package com.example.demo.config;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * ResultCode : 响应封装实现类
 *
 * @author zyw
 * @create 2023/6/15
 */
@AllArgsConstructor
@NoArgsConstructor
public enum ResultCode implements IResultCode, Serializable {

    //短信发送次数超过限制
    EM_SMS_MAX_LIMIT("10001","短信发送次数超过限制"),
    //无效的手机号码
    EM_SMS_INVALID_MOBILE("10002","无效的手机号码");

    @Override
    public String getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }

    private String code;

    private String msg;

    @Override
    public String toString() {
        return "{" +
                "\"code\":\"" + code + '\"' +
                ", \"msg\":\"" + msg + '\"' +
                '}';
    }


    // 默认系统执行错误
    public static ResultCode getValue(String code) {
        for (ResultCode value : values()) {
            if (value.getCode().equals(code)) {
                return value;
            }
        }
        return ECEPTION;
    }
}

7.使用服务类发送短信

在需要发送短信的地方注入SmsService并调用其方法发送短信。

package com.example.demo.controller;

import com.alibaba.fastjson.JSON;
import com.example.demo.sms.SmsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * SmsController : 短信控制器
 *
 * @author zyw
 * @create 2024-06-11  15:56
 */

@RestController
@Tag(name = "短信控制器")
@RequestMapping("sms")
public class SmsController {

    @Resource
    private SmsService smsService;

    @Value("${sms.aliyun.templateCode}")
    private String templateCode;

    //发送短信
    @Operation(summary = "单个手机号发送短信验证码")
    @PostMapping("/SendATextMessageByhone")
    public String SendATextMessageByhone(String mobile, String message) {
        Map<String, String> tempContentMap = new HashMap<>();
        tempContentMap.put("code", String.valueOf(message));
        smsService.sendSms(List.of(mobile), JSON.toJSONString(tempContentMap), templateCode);
        return "短信发送成功";
    }


}

请确保替换成你自己的AccessKey信息、签名、模板CODE等,以及根据实际情况调整参数。此外,考虑到安全性,不要直接在版本控制系统中提交敏感信息,如AccessKey ID和AccessKey Secret,应使用环境变量或外部配置管理服务来管理这些信息。

8.测试短信

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1838139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

奇怪的缓存一致性问题

天猫国际用户Push中心承接了国际用户触达相关的需求&#xff0c;比如短信、端内消息投放等等&#xff0c;并存在较高的并发场景。 该系统此前发现了一个查询投放计划plan为null的异常情况&#xff0c;在初期排查时有些丈二和尚摸不着头脑&#xff0c;后面突然灵光乍现——原来是…

探索线性回归模型

目录 一 线性回归的理论基础 什么是线性回归? 线性回归的假设 最小二乘法 二 线性回归的数学推导 线性回归参数的推导 多元线性回归 三 线性回归的模型构建 数据准备 训练模型 模型评估 四 线性回归的代码实现 基本实现 多元线性回归 五 线性回归的应用场景 预…

pygame游戏开发

Pygame游戏开发 pygame简介 模块库请参考&#xff1a;pygame官方文档 pygame可以用作游戏开发&#xff0c;但在商业游戏中真正的开发工具却不是pygame。使用pygame开发游戏周期长。 安装pygame 在pycharm中安装第三方库pygame&#xff1a; 在计算机中安装pygame&#xf…

C# OCCT Winform 界面搭建

目录 1.创建一个WInform项目 2.代码总览 代码解析 3.添加模型到场景 4.鼠标交互 1.创建一个WInform项目 2.代码总览 using Macad.Occt.Helper; using Macad.Occt; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting.Co…

机器学习课程复习——支持向量机

支持向量机是一种二类分类模型。基本模型:定义在特征空间上的间隔最大的线性分类器模型升级:线性分类器+核技巧=非线性分类器学习策略:间隔最大化(可形式化为求解凸二次规划的问题;可等价于正则化的合页损失函数的最小化问题)学习算法:求解图二次规划的最优化算法支持向…

什么是Linux挂载

首先先说一下在Linux中一切皆文件&#xff08;硬件设备也是文件&#xff09;&#xff0c;所有文件都是存放在以根目录为树形目录结构中&#xff1b;下面来说说一下什么是挂载 挂载&#xff1a;指的就是将设备文件中的顶级目录连接到 Linux 根目录下的某一目录&#xff08;最好是…

架构师篇-1、总体架构设计

业务架构哲学本质 定位&#xff1a;赋予业务架构设计能力&#xff0c;具备业务架构设计思维模型&#xff0c;掌握业务架构哲学本质&#xff0c;形成以不变应万变的业务架构设计能力。 架构师所需要的能力&#xff1a; 带领业务成功通过框架思维赋能业务架构师知识体系构建掌…

如何卸载windows系统自带游戏

为了清晰地指导如何卸载Windows系统自带游戏&#xff0c;我们可以参考以下步骤进行&#xff1a; 方法一&#xff1a;通过控制面板卸载 打开控制面板进入程序和功能在控制面板中&#xff0c;找到并点击“程序和功能”。在程序列表中&#xff0c;找到你想要卸载的自带游戏。 方…

反激开关电源压敏电阻选型及计算

作用:在浪涌时间里面吸收一个很高的浪涌电压 压敏电阻对电压敏感&#xff0c;有变阻电压阈值 在电压阈值以下&#xff0c;表现出阻抗很大&#xff0c;超过电压阈值&#xff0c;表现出阻抗很小 压敏的选型及计算 压敏电阻的作用是抑制来自电源在异常时的尖峰电压和瞬态过电压&a…

C++编程入门,五个学习阶段让你变成高手

C是一门非常复杂而强大的编程语言&#xff0c;涵盖了广泛的知识领域&#xff0c;从语法基础到高级特性&#xff0c;再到网络通信和数据库操作&#xff0c;都需要逐步掌握。如果你是一个编程新手&#xff0c;尤其是对C感兴趣的新手&#xff0c;可能会发现这门语言的学习曲线有些…

【Linux】进程间通信3——system V共享内存

1.system V进程间通信 管道通信本质是基于文件的&#xff0c;也就是说操作系统并没有为此做过多的设计工作&#xff0c;而system V IPC是操作系统特地设计的一种通信方式。但是不管怎么样&#xff0c;它们的本质都是一样的&#xff0c;都是在想尽办法让不同的进程看到同一份由操…

HTML静态网页成品作业(HTML+CSS)——新媒体专业介绍介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

韩国裸机云站群服务器托管租用方案

随着网络技术的飞速发展&#xff0c;站群服务器在网站运营中扮演着越来越重要的角色。韩国裸机云站群服务器&#xff0c;以其独特的优势&#xff0c;如地理位置优越、价格相对较低、技术实力雄厚等&#xff0c;吸引了众多企业的关注。本文将为您详细介绍韩国裸机云站群服务器的…

机器学习课程复习——朴素贝叶斯

1. 定义 是一种基于贝叶斯定理与特征条件独立假设的生成式分类方法。 2. 公式 原版公式 简化版公式 由于上述公式无法计算&#xff0c;引入条件独立假设 条件独立版公式 3. 贝叶斯分类器 由上述公式可得贝叶斯分类器 化简为 4. 参数估计 4.1. 极大似然估计 4.2. 学习与分…

Psim仿真教程-电路仿真软件功能介绍/电源工程师初级到高级进阶之路

点击下面文字下载需要的版本: Psim2022中文版下载链接: Psim2022中文版软件下载地址 Psim9.1经典版本下载链接: Psim 9.1软件下载地址 有了Psim仿真软件后,无论是电气系统设计还是软件控制设计,都让自己有了质的提升,因此对控制领域感兴趣的朋友们,一定要跟着作者去…

ruoyi框架第二天,自定义接口,在若依框架显示数据

书接上文&#xff0c;搭建好若依&#xff0c;并且创建自己想要的模块。 让ruoyi框架显示自己想要的模块。 今天&#xff0c;我们就要自定义接口&#xff0c;模仿ruoyi框架收发数据模式&#xff0c;来创建自己的模块。 我们创建好自己想要的接口&#xff0c;我这个是无参的查…

【面试干货】Java方法重载规则

【面试干货】Java方法重载规则 1、方法重载的规则和注意事项1.1 方法名必须一致1.2 参数列表必须不同1.3 代码示例1.4 与方法的返回值无关1.5 存在于父类和子类或同类中1.6 可以抛出不同的异常1.7 可以有不同的修饰符 2、注意事项3、总结 &#x1f496;The Begin&#x1f496;点…

据APO Research(阿谱尔)统计,2023年全球乳酸企业产能约119.3万吨

乳酸又称 2-羟基丙酸&#xff0c;一种天然有机酸&#xff0c;分子式是 C3H6O3。是自然界中最为广泛存在的羟基酸&#xff0c;于 1780 年被瑞典科学家 Scheele 首次发现。乳酸是自然界最小的手性分子&#xff0c;以两种立体异构体的形式存在于自然界中&#xff0c;即左旋型 L-乳…

白酒:酒文化传承中的挑战与机遇

随着时代的变迁&#xff0c;酒文化传承面临着许多挑战与机遇。我们来看看酒文化传承面临的挑战。随着现代生活方式的改变&#xff0c;人们对于传统酒文化的认知逐渐淡化。与此同时&#xff0c;年轻一代对于酒文化的兴趣不如老一辈浓厚&#xff0c;这使得酒文化的传承面临断层的…

001、DM8安装

参照&#xff1a;https://eco.dameng.com/document/dm/zh-cn/pm/install-uninstall.html 1. 准备工作 操作系统查看 [rootora19c ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)新建用户 [rootora19c ~]# groupadd dinstall -g 2001 [rootora19c ~]# …