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: true
    endpoint: cn-hangzhou
    access-key-id: xxxxxxxx
    access-key-secret: xxxxxxxx
    sign-name: xxxxxxxx
    template-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";

    @Autowired
    private AliyunSmsProperties aliyunSmsProperties;

    @Bean
    @ConditionalOnMissingBean
    public 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;

    @Override
    public boolean send(Collection<String> phones, Map<String, Object> param) {
        return this.send(phones, aliyunSmsProperties.getTemplateCode(), param);
    }

    @Override
    public 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 {

    @Autowired
    private 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.mfbz.cn/a/585936.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

六氟化硫红外吸收峰

特此记录 anlog 2024年4月30日

标准汽车试验铁地板的技术要求

在现代科技化发展的工作中&#xff0c;试验平台被广泛使用。铸铁试验平台&#xff08;试验铁地板&#xff09;又叫试验工作平台&#xff0c;听名字大家也不难想象出来这是一款带有箱式体的台面&#xff0c;这是一种有长方形或者圆形又或者正方形的试验工作台。 铸铁试验平台&a…

Unity类银河恶魔城学习记录15-5,6 p157 Audio time limiter p158 Area sound

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili​​ AreaSound.cs using System.Collections; using System.Collections.G…

一站式AI创作平台:融合GPT会话、GPTs应用、Midjourney视觉艺术与Suno AI音乐合成模块

一、系统简介 星河易创AI系统基于ChatGPT的核心技术打造&#xff0c;集成了自然语言问答和艺术创作功能。该系统兼容Midjourney绘画技术&#xff0c;并支持官方GPT模型。它提供了多样化的应用&#xff0c;包括GPTs的多场景应用、实时GPT语音对话能力、GPT-4模型的先进特性&…

测试腾讯云的高防CC抵御了攻击

网站需要安装防止CC攻击&#xff0c;因为CC攻击是一种常见的网络攻击&#xff0c;它会对网站造成严重的影响。 CC攻击&#xff08;Cybercrime Control&#xff09;是指向网站发起大量虚假请求的攻击&#xff0c;目的是使网站的资源耗尽&#xff0c;无法正常运行。CC攻击与DDoS…

浅谈 HTTPS

文章目录 HTTPS 简介HTTPS 特点与 HTTP 的区别HTTPS 工作流程1. 服务端生成密钥对2. 服务端申请数字证书3. 服务端发送数字证书4. 客户端验证数字证书5. 客户端解析证书内容6. 客户端传送加密信息7. 服务端解密信息8. 双方协商生成会话密钥并交换9. 使用会话密钥进行通信 总结 …

UNI-APP_拨打电话权限如何去掉,访问文件权限关闭

uniapp上架过程中一直提示&#xff1a;允许“app名”拨打电话和管理通话吗&#xff1f; uniapp配置文件&#xff1a;manifest.json “permissionPhoneState” : {“request” : “none”//拨打电话权限关闭 }, “permissionExternalStorage” : {“request” : “none”//访…

vue 前端读取Excel文件并解析

前端读取Excel文件并解析 前端如何解释Excel呢 平时项目中对于Excel的导入解析是很常见的功能&#xff0c;一般都是放在后端执行&#xff1b;但是也有特殊的情况&#xff0c;偶尔也有要求说前端执行解析&#xff0c;判空&#xff0c;校验等&#xff0c;最后组装成后端接口想要的…

JAVA前端快速入门基础_javascript入门(03)

写在前面:本文用于快速学会简易的JS&#xff0c;仅做扫盲和参考作用 本章节主要介绍JS的事件监听 1.什么是事件监听 事件:是指发生在HTML端的事件&#xff0c;主要指以下几种。 1.按钮被点击 2.鼠标移动到元素上 3.按到了键盘 事件监听:当触发了事件时&#xff0c;JS会执行相…

ECharts在网页中添加可视化图标-在网页中添加交互图表+option模块案列详解

一、引言 ECharts 是一个使用 JavaScript 编写的开源可视化库&#xff0c;它可以在浏览器中生成交互式的图表。无论是折线图、柱状图、散点图还是饼图&#xff0c;ECharts 都能轻松应对。本文将带领大家了解如何在网页中添加 ECharts 可视化图标。 本章可以直接跳到第五点完整…

Flask简介

Flask简介 安装概述使用PyCharm创建一个Flask程序 Flask程序的基本结构初始化路由和视图函数启动服务器请求-响应循环 安装 概述 Flask算是小型框架&#xff0c;小到可以称为“微框架”。Flask 非常小&#xff0c;因此你一旦能够熟练使用它&#xff0c;很可能就能读懂它所有的…

Copilot Workspace是GitHub对人工智能驱动的软件工程的诠释

软件开发的未来是人工智能驱动的集成开发环境吗&#xff1f;至少GitHub 是这样想的。 在今年初秋于旧金山举行的 GitHub Universe 年度大会之前&#xff0c;GitHub 发布了 Copilot Workspace&#xff0c;这是一种开发环境&#xff0c;利用 GitHub 所称的 “Copilot 驱动的代理…

OneFlow新概念清单,AI深度学习的革命性突破(AI写作)

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

kotlinDSL控制的安卓项目导入已存在的模块后sync报错

原因很明显&#xff0c;但是我还找了好久 因为在import时并没有选择groove还是kotlin控制&#xff0c; 所以默认为groovy控制的&#xff0c;然而主项目是由kotlin dsl控制的grale行为。 原因清楚之后&#xff0c;就可以去检查一下&#xff0c;项目里是否包含了settings.gradle和…

基于EBAZ4205矿板的图像处理:03使用VIO调试输出HDMI视频图像

基于EBAZ4205矿板的图像处理&#xff1a;03使用VIO调试输出HDMI视频图像 在zynq调试时VIO是真的方便&#xff0c;特此写一篇博客记录一下 先看效果 项目简介 下面是我的BD设计&#xff0c;vtc用于生成时序&#xff0c;注意&#xff0c;2021.2的vivado的vtcIP是v6.2版本&…

动手学深度学习——softmax分类

1. 分类问题 回归与分类的区别&#xff1a; 回归可以用于预测多少的问题&#xff0c; 比如"预测房屋被售出价格"&#xff0c;它是个单值输出。softmax可以用来预测分类问题&#xff0c;例如"某个图片中是猫、鸡还是狗&#xff1f;"&#xff0c;这是一个多…

用Docker 创建并运行一个MySQL容器

可以在DockerHub官网上荡:mysql - Official Image | Docker Hub 指令是:docker pull mysql; 因为文件比较大可能时间比较长&#xff0c;我是跟着黑马的课走的 课程提供的有文件&#xff0c;我就用已有的资源了。 在tmp目录里放入mysql.tar包 然后cd进去 输入指令:docker lo…

java技术栈快速复习05_基础运维(linux,git)

Linux知识总览 linux可以简单的理解成和window一样的操作系统。 Linux和Windows区别 Linux是严格区分大小写的&#xff1b;Linux中一切皆是文件&#xff1b;Linux中文件是没有后缀的&#xff0c;但是他有一些约定俗成的后缀&#xff1b;Windows下的软件一般是无法直接运行的Li…

管理能力学习笔记八:Will-Skill矩阵“盘“团队

如何把握带教中的“度”&#xff0c;才能在把事情做好的基础上&#xff0c;又能使员工获得成长呢&#xff1f; 需要做到 合理授权 & 适当辅导 如何做到&#xff1f; 通过使用 意愿-技能矩阵(Will-Skill Matrix) 辨别不同带教方法的适用情形&#xff0c;"盘"…

【Vue 2.x】学习vue之一基础部分

文章目录 Vue 一基础部分第一章1、git两个分支主分支子分支 使用方法方式1&#xff1a;采用命令的方式操作分支方式2&#xff1a;在idea中使用git的分支 向git远程仓库提交时忽略文件使用git时的一些冲突注意事项 2、Vue问题1&#xff1a;什么是Vue&#xff1f;问题2&#xff1…
最新文章