华为云短信接入实现示例

news2025/5/10 14:29:30

1)构建Springboot项目

2)  添加依赖

<dependency>
     <groupId>com.huawei.apigateway</groupId>
     <artifactId>java-sdk-core</artifactId>
     <version>3.2.4</version>
</dependency>

3) 配置文件

huaweiyun:
  sms:
    url: https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1
    appKey: V******************0
    appSecret: X*******************v
    sender: 8***********9

4) 配置类

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @author admin
 */
@Component
public class SmsConstant implements InitializingBean {

    @Value("${huaweiyun.sms.url}")
    public String smsUrl;
    @Value("${huaweiyun.sms.appKey}")
    public String appKey;
    @Value("${huaweiyun.sms.appSecret}")
    public String appSecret;
    @Value("${huaweiyun.sms.sender}")
    public String smsSender;

    public static String APP_KEY;
    public static String APP_SECRET;
    public static String SMS_URL;
    public static String SMS_SENDER;

    @Override
    public void afterPropertiesSet(){
        APP_KEY = appKey;
        APP_SECRET = appSecret;
        SMS_URL = smsUrl;
        SMS_SENDER = smsSender;
    }

    /*
     * 为了解决base64加密 密钥太长报错问题
     */
    static {
        try {
            Class<?> clazz = Class.forName("javax.crypto.JceSecurity");
            Field nameField = clazz.getDeclaredField("isRestricted");

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL);

            nameField.setAccessible(true);
            nameField.set(null, Boolean.FALSE);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

5)使用枚举类定义短信模板

@AllArgsConstructor
@Getter
public enum MsgTempEnum {

    SMS_VERIFY(1, "短信认证","SMS_VERIFY"),

    FIRE_PUSH_SMS(2, "短信推送","PUSH_SMS"),
    ;

    private final int id;

    private final String name;

    private final String code;

}

6)短信工具类

import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import com.cloud.apigateway.sdk.utils.Client;
import com.cloud.apigateway.sdk.utils.Request;
import com.zxzx.firecloud.module.base.model.entity.Message;
import com.zxzx.firecloud.module.base.model.entity.TempSms;
import com.zxzx.firecloud.module.base.service.IMessageService;
import com.zxzx.firecloud.module.base.service.ITempSmsService;
import com.zxzx.firecloud.module.uc.model.entity.User;
import com.zxzx.firecloud.module.uc.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@Slf4j
@Component
public class SendSms {

    public static final String UTF_8 = "UTF-8";

    @Autowired
    private IMessageService messageService;
    @Autowired
    private ITempSmsService tempSmsService;
    @Autowired
    private IUserService userService;

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, String receiver, String param) {
        return sendSms(msgTempEnum, Collections.singletonList(receiver), Collections.singletonList(param));
    }

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, List<String> receiverList, String param) {
        return sendSms(msgTempEnum, receiverList, Collections.singletonList(param));
    }

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, String receiver, List<String> paramList) {
        return sendSms(msgTempEnum, Collections.singletonList(receiver), paramList);
    }

    public List<SmsResultDetail> sendSms(MsgTempEnum msgTempEnum, List<String> receiverList, List<String> paramList) {
        try {
            TempSms tempSms = tempSmsService.getTempSmsByBusiness(msgTempEnum.getCode());
            String templateId = tempSms.getTemplateId();
            if (ObjUtil.isEmpty(receiverList) || ObjUtil.isEmpty(templateId)) {
                log.error("receiverList or templateId is null");
                return new ArrayList<>();
            }
            String templateParas = "[\"" + StringUtils.join(paramList, "\",\"") + "\"]";
            String receiver = StringUtils.join(receiverList, ",");
            List<SmsResultDetail> responseList = new ArrayList<>();
            try {
                Request request = new Request();
                String body = buildRequestBody(SmsConstant.SMS_SENDER, receiver, templateId, templateParas);
                request.setKey(SmsConstant.APP_KEY);
                request.setSecret(SmsConstant.APP_SECRET);
                request.setUrl(SmsConstant.SMS_URL);
                request.setMethod("POST");
                request.addHeader("Content-Type", "application/x-www-form-urlencoded");
                request.setBody(body);
                HttpRequestBase signedRequest = Client.sign(request, "SDK-HMAC-SHA256");
                HttpResponse response = HttpClientSingleton.getInstance().execute(signedRequest);
                log.info("Print the status line of the response: {}", response.getStatusLine().toString());
                responseList = getResultDetailList(response.getEntity());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            for (SmsResultDetail resultDetail : responseList) {
                Message message = new Message();
                message.setMessageType("SMS");
                message.setMessageContent(MessageFormat.format(tempSms.getTemplateDesc(), paramList.toArray()));
                message.setTitle(tempSms.getName());
                message.setReceiver(resultDetail.getOriginTo());
                message.setCallMessage(resultDetail.toString());
                message.setBusiness(msgTempEnum.getCode());
                message.setStatus(2);
                if ("000000".equals(resultDetail.getStatus())) {
                    message.setStatus(1);
                }
                messageService.save(message);
            }
            return responseList;
        } catch (Exception e) {
            log.error("短信推送失败:{}", e);
            return new ArrayList<>();
        }
    }

    private static List<SmsResultDetail> getResultDetailList(HttpEntity resEntity) throws IOException {
        if (resEntity == null) {
            return new ArrayList<>();
        }
        String res = EntityUtils.toString(resEntity, "UTF-8");
        log.info("Processing Body with name: {} and value: {}", System.getProperty("line.separator"), res);
        SmsResult bean = JSONUtil.toBean(res, SmsResult.class);
        if (bean == null || !"000000".equals(bean.getCode())) {
            return new ArrayList<>();
        }
        List<SmsResultDetail> successList = new ArrayList<>();
        if (ObjUtil.isNotEmpty(bean.getResult())) {
            successList = bean.getResult();
        }
        return successList;
    }

    static String buildRequestBody(String sender, String receiver, String templateId, String templateParas) throws UnsupportedEncodingException {
        StringBuilder body = new StringBuilder();
        appendToBody(body, "from=", sender);
        appendToBody(body, "&to=", receiver);
        appendToBody(body, "&templateId=", templateId);
        appendToBody(body, "&templateParas=", templateParas);
        return body.toString();
    }

    private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException {
        if (ObjUtil.isNotEmpty(val)) {
            body.append(key).append(URLEncoder.encode(val, UTF_8));
        }
    }
}

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

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

相关文章

Linux系统下使用Kafka和Zookeeper

Apache Kafka 是一个分布式流处理平台,最初由 LinkedIn 开发,后来成为 Apache 软件基金会的顶级项目。它具有高吞吐量、可扩展性、持久性、容错性等特点,主要用于处理实时数据流。 Linux系统下使用Kafka 1.安装 Java Kafka 和 Zookeeper 都是基于 Java 开发的,所以需要先…

Unity按钮事件冒泡

今天unity写程序时&#xff0c;我做了一个透明按钮&#xff0c;没图片&#xff0c;只绑了点击事件&#xff0c;把子对象文字组件也删了&#xff0c;空留一个透明按钮&#xff0c;此时运行时点击按钮是没有反应的&#xff0c;网上的教程说必须指定target graphic&#xff08;目标…

指令图像编辑模型:ICEdit-MoE-LoRA

ICEdit-MoE-LoRA 一、研究背景与目标 In-Context Edit 是一种新颖的基于指令的图像编辑方法&#xff0c;旨在实现与现有最佳方法相当甚至更优的编辑效果。传统图像编辑技术在处理复杂指令时存在一定局限性&#xff0c;尤其是在多轮编辑任务中&#xff0c;结果的准确性和连贯性…

捌拾叁- 量子傅里叶变换

1. 前言 最近公司地震&#xff0c;现在稍微有点时间继续学习。 看了几个算法&#xff0c;都说是基于 量子傅里叶变换 &#xff0c;好&#xff0c;就是他了 Quantum Fourier。 2. 傅里叶变换 大学是学通信的&#xff0c;对于傅里叶变换还是有所理解的。其实就是基于一个 时域…

2.在Openharmony写hello world

原文链接&#xff1a;https://kashima19960.github.io/2025/03/21/openharmony/2.在Openharmony写hello%20world/ 前言 Openharmony 的第一个官方例程的是教你在Hi3861上编写hello world程序&#xff0c;这个例程相当简单编写 Hello World”程序&#xff0c;而且步骤也很省略&…

STM32外设-串口UART

STM32外设-串口UART 一&#xff0c;串口简介二&#xff0c;串口基础概念1&#xff0c;什么是同步和异步/UART与USART对比2&#xff0c;串行与并行3&#xff0c;波特率 (Baud Rate)4&#xff0c;数据帧 (Data Frame)5&#xff0c;TX 和 RX 三&#xff0c;硬件连接1&#xff0c;u…

MCU存储系统架构解析

今天和大家分享一下MCU存储器层次结构的设计思路。这种分层存储架构通过整合不同特性的存储单元&#xff0c;能够很好地平衡性能与成本需求。 首先是寄存器层&#xff0c;它直接集成在CPU内核里&#xff0c;速度最快&#xff08;纳秒级&#xff09;&#xff0c;但容量比较小&a…

Linux——MySQL基础

基础知识 连接服务器 mysql -h 127.0.0.1 -P 3306 -u root -p -h 指明登录部署了myqsl服务的主机 -P 指明访问的端口号 -u 指明用户 -p 指明登录密码&#xff08;可以不填写&#xff09; 什么是数据库 首先&#xff0c;数据库是分为服务端和客户端的&#xff1a; mysql是客户…

OpenGl实战笔记(2)基于qt5.15.2+mingw64+opengl实现纹理贴图

一、作用原理 1、作用&#xff1a;将一张图片&#xff08;纹理&#xff09;映射到几何体表面&#xff0c;提升视觉真实感&#xff0c;不增加几何复杂度。 2、原理&#xff1a;加载图片为纹理 → 上传到 GPU&#xff1b;为顶点设置纹理坐标&#xff08;如 0~1 范围&#xff09;&…

【计算机视觉】OpenCV实战项目: opencv-text-deskew:实时文本图像校正

opencv-text-deskew&#xff1a;基于OpenCV的实时文本图像校正 一、项目概述与技术背景1.1 核心功能与创新点1.2 技术指标对比1.3 技术演进路线 二、环境配置与算法原理2.1 硬件要求2.2 软件部署2.3 核心算法流程 三、核心算法解析3.1 文本区域定位3.2 角度检测优化3.3 仿射变换…

Java 23种设计模式 - 结构型模式7种

Java 23种设计模式 - 结构型模式7种 1 适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 优点 将目标类和适配者类解耦增加了类的透明性和复用性&#xff0c;将具体的实现封…

数据库(MySQL)基础

一、登录数据库 在linux系统中登录数据库的指令 mysql -h 127.48.0.236 -P 3306 -u root -p -h&#xff1a;填写IP地址&#xff0c;指明要连接的主机。如果不加该字段表示本地主机-P&#xff1a;填写端口号&#xff0c;指明进程。 如果不加该字段会使用默认的端口号。-u&…

Vue 2.0 详解全教程(含 Axios 封装 + 路由守卫 + 实战进阶)

目录 一、Vue 2.0 简介1.1 什么是 Vue&#xff1f;1.2 Vue 2.x 的主要特性 二、快速上手2.1 引入 Vue2.2 创建第一个 Vue 实例 三、核心概念详解3.1 模板语法3.2 数据绑定3.3 事件绑定3.4 计算属性 & 侦听器 四、组件系统4.1 定义全局组件4.2 单文件组件&#xff08;*.vue …

依赖关系-根据依赖关系求候选码

关系模式R&#xff08;U, F&#xff09;, U{}&#xff0c;F是R的函数依赖集&#xff0c;可以将属性分为4类&#xff1a; L: 仅出现在依赖集F左侧的属性 R: 仅出现在依赖集F右侧的属性 LR: 在依赖集F左右侧都出现的属性 NLR: 在依赖集F左右侧都未出现的属性 结论1: 若X是L类…

uniapp-商城-47-后台 分类数据的生成(通过数据)

在第46章节中&#xff0c;我们为后台数据创建了分类的数据表结构schema&#xff0c;使得可以通过后台添加数据并保存&#xff0c;同时使用云函数进行数据库数据的读取。文章详细介绍了如何通过前端代码实现分类管理功能&#xff0c;包括获取数据、添加、更新和删除分类。主要代…

java-----------------多态

多态&#xff0c;当前指的是 java 所呈现出来的一个对象 多态 定义 多态是指同一个行为具有多个不同表现形式或形态的能力。在面向对象编程中&#xff0c;多态通过方法重载和方法重写来实现。 强弱类型语言 javascript 或者python 是弱类型语言 C 语言&#xff0c;或者 C…

【文档智能】开源的阅读顺序(Layoutreader)模型使用指南

一年前&#xff0c;笔者基于开源了一个阅读顺序模型&#xff08;《【文档智能】符合人类阅读顺序的文档模型-LayoutReader及非官方权重开源》&#xff09;&#xff0c; PDF解析并结构化技术路线方案及思路&#xff0c;文档智能专栏 阅读顺序检测旨在捕获人类读者能够自然理解的…

Edu教育邮箱申请2025年5月

各位好&#xff0c;这里是aigc创意人竹相左边 如你所见&#xff0c;这里是第3部分 现在是选择大学的学科专业 选专业的时候记得考虑一下当前的时间日期。 比如现在是夏天&#xff0c;所以你选秋天入学是合理的。

STM32-TIM定时中断(6)

目录 一、TIM介绍 1、TIM简介 2、定时器类型 3、基本定时器 4、通用定时器 5、定时中断基本结构 6、时基单元的时序 &#xff08;1&#xff09;预分频器时序 &#xff08;2&#xff09;计数器时序 7、RCC时钟树 二、定时器输出比较功能&#xff08;PWM&#xff09; …

Modbus RTU 详解 + FreeMODBUS移植(附项目源码)

文章目录 前言一、Modbus RTU1.1 通信方式1.2 模式特点1.3 数据模型1.4 常用功能码说明1.5 异常响应码1.6 通信帧格式1.6.1 示例一&#xff1a;读取保持寄存器&#xff08;功能码 0x03&#xff09;1.6.2 示例二&#xff1a;写单个线圈&#xff08;功能码 0x05&#xff09;1.6.3…