Springboot部署阿里云短信服务

news2024/11/26 4:38:59

一、阿里云短信模板配置(获取SignName[签名名称]、TemplateCode[模板CODE])

1. 进入阿里云首页直接搜索短信服务,并点击国内消息进入国内文本短信管理页面

短信服务-国内消息管理页面

2. 选择签名管理点击添加签名

签名管理页面

填写签名信息并提交

注:下面的签名来源如项目未上线可选择测试或学习(我上面的一个签名就是测试的)。
添加签名页面

3. 选择模板管理点击添加模板

模板管理页面

填写模板信息

添加模板页面

注:因签名与模板的审核都需要时间,且模板依赖于签名,如有需要可直接提交两个签名申请,减少连续等待的审核时间。

利用上面的审核时间我们就可以继续配置其他信息。

二、阿里云AccessKey配置(获取AccessKeyId、AccessKeySecret)

1. 创建专用于短信服务访问的RAM用户,导航栏搜索RAM用户,并点击创建用户

RAM用户页面

2. 填写RAM用户信息

创建用户信息页面

3.保存AccessKeyId、AccessSecret

创建成功页面

4. 为创建的用户添加权限

添加权限页面

以上便可让我们获取到accessKeyId、accessKeySecret、signName、templateCode用于项目部署的配置

三、Springboot的配置

1. application.yml文件添加配置信息

#阿里云短信发送配置信息
sms:
    AccessKeyId:
    accessKeySecret:
    signName:
    templateCode: 
    doMain:dysmsapi.aliyuncs.com
    regionId:cn-hangzhou

2. pom.xml文件添加依赖

https://mvnrepository.com/

		<dependency>
			<groupId>com.aliyun</groupId>
			<artifactId>aliyun-java-sdk-core</artifactId>
			<version>4.5.16</version>
		</dependency>
		<dependency>
			<groupId>com.aliyun</groupId>
			<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
			<version>1.0.0</version>
		</dependency>
		<!--这个springboot是有自动集成的-->
<!--		<dependency>-->
<!--			<groupId>com.google.code.gson</groupId>-->
<!--			<artifactId>gson</artifactId>-->
<!--			<version>2.8.5</version>-->
<!--		</dependency>-->

然后重新加载Maven下载依赖。

3. Controller控制层

package com...business.controller;

import com.hy.erp.business.service.SendSmsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@RequestMapping("/sms")
public class SendSmsController {
    @Autowired
    private SendSmsService sendSmsService;

    @ResponseBody
    @RequestMapping(value = "/sendSms")
    public String sendSms() {
        String message = SendSmsController.randomCode(4).toString();
        boolean sendFlag = sendSmsService.sendSms("183****6666",message);
        if (sendFlag){
            return "短信发送成功,请注意查收。";
        }else {
            return "短信发送失败!";
        }
    }

    //随机生成指定位数验证码
    public static StringBuffer randomCode(int number){
        //验证码内容集
        final char[] CHARS = {
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
        StringBuffer stringBuffer=new StringBuffer();
        Random r=new Random();
        for(int i=0;i<number;i++){
            stringBuffer.append(CHARS[r.nextInt(CHARS.length)]);
        }
        return stringBuffer;
    }
}

4. Service业务层

package com.hy.erp.business.service;

public interface SendSmsService {

	/**
	 * 发送短信的接口
	 *
	 * @param phoneNum 手机号
	 * @param message 消息
	 * @return
	 */
	boolean sendSms(String phoneNum, String message);
}

5. 实现层

package com.hy.erp.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.hy.erp.business.service.SendSmsService;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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


@Service
@Data
public class SendSmsServiceImpl implements SendSmsService {
    private static final Logger logger = LoggerFactory.getLogger(SendSmsServiceImpl.class);
    //application.yml文件里配置的sms
    @Value("${sms.accessKeyId}")
    private String accessKeyId;
    @Value("${sms.accessKeySecret}")
    private String accessKeySecret;
    //短信api的请求地址 固定的 dysmsapi.aliyuncs.com
    @Value("${sms.doMain}")
    private String doMain;
    //指定地域名称 短信API固定的 cn-hangzhou
    @Value("${sms.regionId}")
    private String regionId;
    //您的申请签名
    @Value("${sms.signName}")
    private String signName;
    //你的模板
    @Value("${sms.templateCode}")
    private String templateCode;

    /**
     * 发送短信接口
     *
     * @param phoneNum 手机号
     * @param message 消息
     * @return
     */
    @Override
    public boolean sendSms(String phoneNum, String message) {

        // 指定地域名称 短信API的就是 cn-hangzhou 不能改变  后边填写您的  accessKey 和 accessKey Secret
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        // 创建通用的请求对象
        CommonRequest request = new CommonRequest();
        // 指定请求方式
        request.setSysMethod(MethodType.POST);
        // 短信api的请求地址  固定
        request.setSysDomain(doMain);
        //签名算法版本  固定
        request.setSysVersion("2017-05-25");
        //请求 API 的名称
        request.setSysAction("SendSms");
        //指定地域名称
        request.putQueryParameter("RegionId", regionId);
        // 要给哪个手机号发送短信  指定手机号
        request.putQueryParameter("PhoneNumbers", phoneNum);
        // 您的申请签名
        request.putQueryParameter("SignName", signName);
        // 您申请的模板 code
        request.putQueryParameter("TemplateCode", templateCode);

        Map<String, Object> params = new HashMap<>();
        //这里的code就是短信模板中的 ${code},可能会有多个参数
        params.put("code", message);

        // 放入参数  需要把 map转换为json格式  使用fastJson进行转换
        request.putQueryParameter("TemplateParam", JSON.toJSONString(params));

        try {
            CommonResponse response = client.getCommonResponse(request);
            logger.info(JSON.parseObject(response.getData(), Map.class).get("Message").toString());
            return response.getHttpResponse().isSuccess();

        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }

        return false;
    }
}

到这里配置好手机号就可以启动项目啦

6.项目启动

如果签名是正确的,后台出现如下信息那便是发送成功

2023-02-09 09:21:18.736  INFO 26032 --- [nio-8888-exec-2] c.h.e.b.service.impl.SendSmsServiceImpl  : 只能向已回复授权信息的手机号发送

可以在阿里云平台配置测试接收信息的手机号

绑定测试手机号

7. 启动问题

  • NoSuchMethodError
java.lang.NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)Lcom/google/gson/JsonElement;
  • NoClassDefFoundError
java.lang.NoClassDefFoundError: Could not initialize class com.aliyuncs.endpoint.LocalConfigRegionalEndpointResolver

首次执行会触发第一种报错,后面执行的都会触发第二种。
开始以为是gson类的问题,找了很久也重新在pom文件后面补上了依赖,后面发现springboot已经自动集成了。
最后发现是aliyun-java-sdk-core的版本问题,我用的4.6.0就会报错,改为4.5.16就运行正常了,你们可以试试其他的。

好了以上都是自己实操后又再走一遍记录下来的,共勉!

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

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

相关文章

全栈自动化测试技术笔记(一):前期调研怎么做

昨天下午在家整理书架&#xff0c;把很多看完的书清理打包好&#xff0c;预约了公益捐赠机构上门回收。 整理的过程中无意翻出了几年前的工作记事本&#xff0c;里面记录了很多我刚开始做自动化和性能测试时的笔记。 虽然站在现在的角度来看&#xff0c;那个时候无论是技术细…

【Java 面试合集】描述下Objec类中常用的方法(未完待续中...)

描述下Objec类中常用的方法 1. 概述 首先我们要知道Object 类是所有的对象的基类&#xff0c;也就是所有的方法都是可以被重写的。 那么到底哪些方法是我们常用的方法呢&#xff1f;&#xff1f;&#xff1f; cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringw…

你知道 GO 中什么情况会变量逃逸吗?

你知道 GO 中什么情况会变量逃逸吗&#xff1f;首先我们先来看看什么是变量逃逸 Go 语言将这个以前我们写 C/C 时候需要做的内存规划和分配&#xff0c;全部整合到了 GO 的编译器中&#xff0c;GO 中将这个称为 变量逃逸 GO 通过编译器分析代码的特征和代码的生命周期&#x…

在RT-Thread STM32F407平台下配置SPI flash为U盘

记录下SPI Flash U盘实现过程中踩过的坑&#xff0c;与您分享。前提条件是&#xff0c;需要先将SPI Flash 配置到elm fal文件系统&#xff0c;并挂载成功。如下图然后开始配置USB1&#xff0c;在CubeMX&#xff0c;选择SUB_OTG_FS2 选择USB Device3&#xff0c;确认USB时钟为48…

流程控制之循环

文章目录五、流程控制之循环5.1 步进循环语句for5.1.1 带列表的for循环语句5.1.2 不带列表的for循环语句5.1.3 类C风格的for循环语句5.2 while循环语句5.2.1 while循环读取文件5.2.2 while循环语句示例5.3 until循环语句5.4 select循环语句5.5 嵌套循环5.4 利用break和continue…

【八大数据排序法】堆积树排序法的图形理解和案例实现 | C++

第二十一章 堆积树排序法 目录 第二十一章 堆积树排序法 ●前言 ●认识排序 1.简要介绍 2.图形理解 3.算法分析 ●二、案例实现 1.案例一 ● 总结 前言 排序算法是我们在程序设计中经常见到和使用的一种算法&#xff0c;它主要是将一堆不规则的数据按照递增…

BinaryAI全新代码匹配模型BAI-2.0上线,“大模型”时代的安全实践

导语BinaryAI&#xff08;https://www.binaryai.net&#xff09;科恩实验室在2021年8月首次发布二进制安全智能分析平台—BinaryAI&#xff0c;BinaryAI可精准高效识别二进制文件的第三方组件及其版本号&#xff0c;旨在推动SCA&#xff08;Software Composition Analysis&…

网络通信协议是什么?

网络通信基本模式 常见的通信模式有如下2种形式&#xff1a;Client-Server(CS) 、 Browser/Server(BS) 实现网络编程关键的三要素 IP地址&#xff1a;设备在网络中的地址&#xff0c;是唯一的标识。 端口&#xff1a;应用程序在设备中唯一的标识。 协议: 数据在网络中传输的…

7、单行函数

文章目录1 函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数及分类2 数值函数2.1 基本函数2.2 角度与弧度互换函数2.3 三角函数2.4 指数与对数2.5 进制间的转换3 字符串函数4 日期和时间函数4.1 获取日期、时间4.2 日期与时间戳的转换4.3 获取月份、星期、星…

码上掘金实现电子木鱼

前言 前几天在朋友圈看到“敲电子木鱼”的视频&#xff0c;敲一下木鱼就提示“功德 1”&#xff0c;还带有敲击声和念经的声音&#xff0c;感觉挺有意思的。 心血来潮&#xff0c;捣鼓了一晚上&#xff0c;借助码上掘金实现了这个功能。 展示效果 素材 准备素材如下&#…

又一国产开源项目走向世界,百度RPC框架Apache bRPC正式成为ASF顶级项目

2023 年 1 月 26 日&#xff0c;Apache 软件基金会 (ASF) 官方正式宣布Apache bRPC 正式毕业&#xff0c;成为 Apache的顶级项目。 我听到这个消息是挺开心的&#xff0c;毕竟是又一款由国人主导的apche顶级项目&#xff0c;再次证明国内在开源界正在发挥越来越重要的作用。 …

Java的对象和类

名词解释 对象是指由类定义的数据结构&#xff0c;拥有属性和方法。它是运行时实例化的。 类是一种用于描述对象的模板&#xff0c;它定义了对象的属性和方法。类是一种类型&#xff0c;可以用于定义对象&#xff0c;并且可以对对象进行操作。 故事概要 小明是初学者想要学习…

JVM——7JVM调优实战及常量池详解

Arthas工具的使用 阿里巴巴开源的java诊断工具 下载插件 上传至linux环境 在linux跑起来的java项目&#xff0c;可以用Arthas进行查看 项目上线前的时候没问题&#xff0c;上线了就出问题 &#xff0c;用来查看线上代码 jad 项目名 &#xff1a;反编译线上正在运行的代码 用…

SpringCloud-Netflix学习笔记10——Hystrix实现服务熔断

一、概述 1、分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系&#xff0c;每个依赖关系在某些时候将不可避免的失败&#xff01; 2、服务雪崩 多个微服务之间调用的时候&#xff0c;假设微服务A调用微服务B和微服务C&#xff0c;微服务B 和微服务C又…

雁过留痕,竟是病毒的痕迹?

凌恩生物全新升级宏病毒组分析流程&#xff1b;聚焦DNA&#xff0c;RNA病毒组研究热点&#xff1b;高灵敏度检测vOTUs&#xff1b;多软件整合&#xff0c;精准鉴定病毒序列&#xff1b;直击地化循环关键环节&#xff0c;助力宏病毒组科研成功&#xff01;期刊&#xff1a;Micro…

板子登录和挂载问题记录

ubuntu登录板子问题 ssh登录ssh 10.1.3.15&#xff0c;显示No route to host 则尝试在板子上ping 本机ip 试一下 挂载 本地机器vim /etc/export编辑此内容并保存 /exports_0209/tda4_build *(rw,no_root_squash,nohide,insecure,no_subtree_check,async)1.挂载nfs方法 mou…

【PR】零基础快速入门教程

【PR】零基础快速入门教程PR&#xff08;Premiere&#xff09;能做什么&#xff1f;PR欢迎界面及新建项目工作区及窗口说明导入文件建立序列视频剪辑添加字幕导出视频使用软件&#xff1a;Premiere2020新年卷起来&#xff0c;写文章已近不能满足与我了&#xff0c;我要向着更前…

MySQL存储过程的传参和流程控制

目录 一.存储过程传参—in 演示 二.存储过程传参—out 演示 三.存储过程传参—inout 演示 四.流程控制—判断 格式 演示 五.流程控制—case 语法 演示 六.流程控制—循环 循环—while 循环—repeat 循环—loop 一.存储过程传参—in in表示传入的参数&#xff0c;可以传…

Java中动态调用setter以及getter

0x00 前言 对于非专业程序员的安全人员来说&#xff0c;因为没有代码项目的积累&#xff0c;很多知识体系都不完善&#xff0c;所以有必要在一些常用的内容进行学习的总结。 在很多的调用链中都会用到**“动态调用setter以及getter”**这个知识点&#xff0c;比如经典的CB链&a…

Jetpack之Lifecycle应用与源码分析

Build lifecycle-aware components that can adjust behavior based on the current lifecycle state of an activity or fragment. 上面是源于官网的定义&#xff0c;简单翻译就是说Lifecycle的作用就是基于当前的Activity或者Fragment的生命周期当前状态构建可感知生命周期的…