SpringBoot使用阿里云实现短信功能

引入依赖

<!-- 阿里云依赖 -->
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.6.3</version>
</dependency>
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>2.2.1</version>
</dependency>

配置文件

# 阿里云短信配置
sms:aliyun:enabled: trueendpoint: cn-hangzhouaccess-key-id: xxxxxxxxaccess-key-secret: xxxxxxxxsign-name: xxxxxxxxtemplate-code: xxxxxxxx

属性类

package com.qiangesoft.sms.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** 阿里云短信属性** @author qiangesoft* @date 2024-04-30*/
@Data
@ConfigurationProperties(prefix = "sms.aliyun")
public class AliyunSmsProperties {/*** 是否启用*/private boolean enabled = true;/*** Endpoint*/private String endpoint;/*** accessKeyId*/private String accessKeyId;/*** accessKeySecret*/private String accessKeySecret;/*** 短信签名*/private String signName;/*** 模板code*/private String templateCode;}

配置类

package com.qiangesoft.sms.config;import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 阿里云短信配置** @author qiangesoft* @date 2024-04-30*/
@Configuration
@EnableConfigurationProperties(AliyunSmsProperties.class)
@ConditionalOnProperty(prefix = "sms.aliyun", name = "enabled", havingValue = "true")
public class AliyunSmsConfiguration {private static final String PRODUCT = "Dysmsapi";private static final String DOMAIN = "dysmsapi.aliyuncs.com";@Autowiredprivate AliyunSmsProperties aliyunSmsProperties;@Bean@ConditionalOnMissingBeanpublic IAcsClient acsClient() {String endPoint = aliyunSmsProperties.getEndpoint();String accessKeyId = aliyunSmsProperties.getAccessKeyId();String accessKeySecret = aliyunSmsProperties.getAccessKeySecret();IClientProfile profile = DefaultProfile.getProfile(endPoint, accessKeyId, accessKeySecret);DefaultProfile.addEndpoint(endPoint, PRODUCT, DOMAIN);return new DefaultAcsClient(profile);}}

短信发送实现

package com.qiangesoft.sms.handler;import org.apache.commons.lang3.StringUtils;import java.util.Collection;
import java.util.Collections;
import java.util.Map;/*** 短信处理器** @author qiangesoft* @date 2024-04-30*/
public interface SendHandler {/*** 发送短信** @param phones* @param param* @return*/boolean send(Collection<String> phones, Map<String, Object> param);/*** 发送短信** @param phone* @param param* @return*/default boolean send(String phone, Map<String, Object> param) {if (StringUtils.isBlank(phone)) {return false;}return send(Collections.singletonList(phone), param);}/*** 发送短信** @param phones* @param templateCode* @param param* @return*/boolean send(Collection<String> phones, String templateCode, Map<String, Object> param);/*** 发送短信** @param phone* @param templateCode* @param param* @return*/default boolean send(String phone, String templateCode, Map<String, Object> param) {if (StringUtils.isBlank(phone)) {return false;}return send(Collections.singletonList(phone), param);}
}
package com.qiangesoft.sms.handler;import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.qiangesoft.sms.config.AliyunSmsProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;import java.util.Collection;
import java.util.Map;/*** 阿里云短信处理器** @author qiangesoft* @date 2023-05-16*/
@Slf4j
@RequiredArgsConstructor
@Service
public class AliyunSendHandler implements SendHandler {private final IAcsClient acsClient;private final AliyunSmsProperties aliyunSmsProperties;@Overridepublic boolean send(Collection<String> phones, Map<String, Object> param) {return this.send(phones, aliyunSmsProperties.getTemplateCode(), param);}@Overridepublic boolean send(Collection<String> phones, String templateCode, Map<String, Object> param) {SendSmsRequest request = new SendSmsRequest();request.setSysMethod(MethodType.POST);request.setPhoneNumbers(StringUtils.join(phones, ","));request.setSignName(aliyunSmsProperties.getSignName());request.setTemplateCode(aliyunSmsProperties.getTemplateCode());request.setTemplateParam(JSONObject.toJSONString(param));try {SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);if ("OK".equals(sendSmsResponse.getCode())) {return true;}log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage());} catch (Exception e) {log.debug(e.getMessage(), e);}return false;}}

测试

package com.qiangesoft.sms.controller;import com.qiangesoft.sms.handler.SendHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;/*** 短信测试** @author qiangesoft* @date 2024-04-30*/
@RequestMapping("/sms")
@RestController
public class SmsController {@Autowiredprivate SendHandler sendHandler;@GetMapping("/send")public Boolean send() {Map<String, Object> param = new HashMap<>();param.put("name", "张三");param.put("jds", 111);param.put("adds", "顶顶顶帆帆");return sendHandler.send("15222222222", param);}}

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

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

相关文章

JavaScript中的扩展操作符作用是什么,有什么含义?

在 JavaScript 中&#xff0c;扩展操作符允许一个表达式在某些地方展开成多个元素。这个特性在 ES2015 (也叫做 ES6) 中被引入到 JavaScript 语言中&#xff0c;并广泛用于数组和对象。在您的代码示例中&#xff0c;它被用于对象。 对象中的扩展操作符 在对象字面量中使用扩展…

SolidWorks进行热力学有限元分析二、模型装配

1.先打开软件&#xff0c;新建装配体 2.选中你要装配的零件&#xff0c;直接导入就行 3.鼠标点击左键直接先放进去 4.开始装配&#xff0c;点配合 5.选择你要接触的两个面&#xff0c;鼠标右键确定&#xff0c;然后把剩下的面对齐一下就行了 6.搞定

代码随想录day60 | 动态规划P17 | ● 647. ● 516.● 动态规划总结篇

今天 结束动态规划章节 正好是60天 fighting 647. 回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的…

Terraform输出值

如果把Terraform代码看作是一个函数的话&#xff0c;那么“输入变量”是函数的参数&#xff0c;而“局部值”是函数内部的局部变量&#xff0c;“输出值”就是函数的返回值。 在Terraform代码中可以定义多个输出值。 在执行terraform apply命令成功之后会打印出定义的输出值信息…

Day1| Java基础 | 1 面向对象特性

Day1 | Java基础 | 1 面向对象特性 基础补充版Java中的开闭原则面向对象继承实现继承this和super关键字修饰符Object类和转型子父类初始化顺序 多态一个简单应用在构造方法中调用多态方法多态与向下转型 问题回答版面向对象面向对象的三大特性是什么&#xff1f;多态特性你是怎…

嵌入式学习

笔记 作业 将一张bmp图片修改成德国国旗。 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #in…

基于vue.js+thymeleaf模板引擎+ajax的注册登陆简洁模板(含从零到一详细介绍)

文章目录 前言1、数据库准备2、工具类与相关基类使用2.1、工具类2.2、相关基类 3、web包目录说明4、注册功能设计&#xff08;本文核心部分&#xff09;4.1、注册页面设计4.2、注册逻辑设计 5、登陆功能设计5.1、登陆页面设计5.2、登陆逻辑设计 6、运行效果图 前言 大多数的网…

【初阶数据结构】单链表之环形链表

目录标题 前言环形链表的约瑟夫问题环形链表环形链表|| 前言 前面我们已经学习了关于单链表的一些基本东西&#xff0c;今天我们来学习单链表的一个拓展——环形链表&#xff0c;我们将用力扣和牛客网上的三道题目来分析讲解环形链表问题。 环形链表的约瑟夫问题 我们首先来看…

利用干扰源模型确定多通道盲源分离

在现实世界的应用中&#xff0c;通常需要从多个麦克风采集的混合信号中提取出感兴趣的源信号。源分离技术主要有两种范式&#xff1a;波束形成&#xff08;beamforming&#xff09;和基于独立成分分析&#xff08;ICA&#xff09;的多通道盲音频源分离&#xff08;MBASS&#x…

Transformer详解:从放弃到入门(三)

上篇文章中我们了解了多头注意力和位置编码&#xff0c;本文我们继续了解Transformer中剩下的其他组件。 层归一化 层归一化想要解决一个问题&#xff0c;这个问题在Batch Normalization的论文中有详细的描述&#xff0c;即深层网络中内部结点在训练过程中分布的变化问题。  …

高效工作之:开源工具kettle实战

在运营商数据处理领域&#xff0c;Oracle存储过程一直是数据处理的核心工具&#xff0c;但随着技术的发展&#xff0c;寻找替代方案变得迫切。Kettle&#xff0c;作为Oracle存储过程的替代品&#xff0c;以其强大的功能和易用性&#xff0c;正逐渐受到运营商的青睐。本文将介绍…

C数据结构:链表高级篇

单链表的定义 由于顺序表的插入删除操作需要移动大量的元素&#xff0c;影响了运行效率&#xff0c;因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素&#xff0c;不需要使用地址连续的存储单元&#xff0c;因此它不要求在逻辑上相…

短视频矩阵系统ai剪辑 矩阵 文案 无人直播四合一功能核心独家源头saas开发

抖去推矩阵AI小程序是一款针对短视频平台的智能创作和运营工具&#xff0c;它具有以下功能特点&#xff1a; 1.批量视频生成&#xff1a;抖去推可以在短时间内生成大量视频&#xff0c;帮助商家快速制作出适合在短视频平台上推广的内容 2.全行业覆盖&#xff1a;适用于多个行业…

MAC M1电脑部署Grafana+Prometheus+Node_exporter

一、安装 1、grafana安装 brew install grafana 2、prometheus安装 brew install prometheus 3、node_exporter安装 brew install node_exporter 二、启动 1、grafana启动 brew services start grafana 2、prometheus启动 brew services start prometheus 3、node_exporter启动…

品深茶的抗癌功能是否涉及虚假宣传?

品深茶说到底&#xff0c;本质还是中国传统茶叶&#xff0c;茶叶本就是一种含有多种成分的饮品&#xff0c;包括茶多酚、生物碱、氨基酸、有机酸等。这些成分对人体有一定的益处&#xff0c;如抗氧化、抗炎、抗菌等作用。 一些研究表明&#xff0c;茶叶中的某些成分如茶多酚、…

Map集合的实现类~TreeMap

重复依据&#xff1a;通过对键进行排序 先创建Student类&#xff0c;并在主函数new对象&#xff0c;然后创建TreeMap&#xff1a; 建立红黑树&#xff0c;需要在Student类后面实现类的接口&#xff1a; 重写其中的compareTo方法&#xff1a; 或者可以自定义比较器&#xff1a; …

自动语音识别

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

每天五分钟计算机视觉:通过交并比判断对象检测算法的性能

本文重点 在对象检测领域,交并比(Intersection over Union,简称IoU)是衡量算法性能的重要指标之一。它不仅直观地反映了预测框与真实框之间的重叠程度,还是判断算法是否“运行良好”的关键依据。 那个定位是好的? 对象检测任务中,我们希望不仅检测到对象,同时我们还希…

最新版Ceph( Reef版本)块存储简单对接k8s

当前ceph 你的ceph集群上执行 1.创建名为k8s-rbd 的存储池 ceph osd pool create k8s-rbd 64 642.初始化 rbd pool init k8s-rbd3 创建k8s访问块设备的认证用户 ceph auth get-or-create client.kubernetes mon profile rbd osd profile rbd pool=k8s-rbd部署 ceph-rbd-csi …

Android 适配阿拉伯语之vector图标镜像

Android 适配阿拉伯语之vector图标镜像 android:autoMirrored“true” 属性简单而直接的方法来自动处理 RTL 环境中图标的翻转。 使用 android:autoMirrored“true” 在 Vector Drawable 中是一种非常方便的方法&#xff0c;因为它允许你使用相同的 drawable 资源来适应不同的…