Spring-Boot整合阿里云短信

简介

1.短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力。 调用API或用群发助手,即可发送验证码、通知类和营销短信; 国内验证短信秒级触达,到达率99%; 国际/港澳台短信覆盖200多个国家和地区,安全稳定,广受出海企业选用。

本次用到的技术

  • 需要熟悉 Spring Boot 操作流程
  • 会使用 Maven
  • 懂得基本的 Redis 操作
  • HTML 基础
首先需要去 阿里云官网获取您的 AccessKey 和 AccessKey Secert

获取AccessKey地址

准备工作

  • 打开阿里云的 sms 控制台
  • 阿里云SMS控制台
  • 可以 先在控制台中选择 快速 学习先看下基本的操作 可以测试基本短信发送 !

image

国内消息 => 签名管理 => 添加签名

image

国内消息 => 签名管理 =>创建模板

image

申请成功之后

  • 记住签名的名称 和模板Code
    待会要使用

image

一、开始整合

1.创建Spring-Boot项目

2.pom.xml依赖

 <!--Aliyun sms Begin-->
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.1.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.67</version>
</dependency>
<!--Aliyun sms end-->

<!--Redis Begin-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--Redis End-->

3.可以先打开Test测试一下

package swy.plus.springbootaliyunsms;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
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 org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

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

@SpringBootTest
class SpringbootaliyunsmsApplicationTests {

    @Test
    void sendSms() {

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

        // 创建通用的请求对象
        CommonRequest request = new CommonRequest();
        // 指定请求方式
        request.setMethod(MethodType.POST);
        // 短信api的请求地址  固定
        request.setDomain("dysmsapi.aliyuncs.com");
        // 签名算法版本  固定
        request.setVersion("2017-05-25");
        //请求 API 的名称。
        request.setAction("SendSms");
        // 上边已经指定过了 这里不用再指定地域名称
//        request.putQueryParameter("RegionId", "cn-hangzhou");
        // 您的申请签名
        request.putQueryParameter("SignName", "您的签名名称");
        // 您申请的模板 code
        request.putQueryParameter("TemplateCode", "您的模板code");
        // 要给哪个手机号发送短信  指定手机号
        request.putQueryParameter("PhoneNumbers", "要发送的手机号");

        // 创建参数集合
        Map<String, Object> params = new HashMap<>();
        // 生成短信的验证码
        String code = String.valueOf(Math.random()).substring(3, 9);
        // 这里的key就是短信模板中的 ${xxxx}
        params.put("code", code);

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

        try {
            // 发送请求 获得响应体
            CommonResponse response = client.getCommonResponse(request);
            // 打印响应体数据
            System.out.println(response.getData());
            // 打印 请求状态 是否成功
            System.out.println(response.getHttpResponse().isSuccess());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
}
4.测试结果

image

# 响应数据
{"Message":"OK","RequestId":"E18E096C-CF46-431C-B81E-14AD8F564994","BizId":"490017688565398557^0","Code":"OK"}
# 是否请求成功
true

二、创建Service

1.修改application.yml配置文件

server:
  port: 8080
spring:
  redis:
    host: 192.168.189.130
    port: 6379
    password: root
aliyun:
  accessKeyID: 你的accessKeyID
  accessKeySecret: 你的accessKeySecret

2.创建service

package swy.plus.springbootaliyunsms.cn.swy.sms.service;

/**
 * Spring-Boot-AliyunSms
 * 2020-07-17 12:00
 * swy.plus.springbootaliyunsms.cn.swy.sms.service
 * 10456
 */
public interface SendSmsService {
    /**
     * 发送短信验证码的接口
     *
     * @param phoneNum 手机号
     * @param code     验证码
     * @return
     */
    boolean sendSms(String phoneNum, String code);
}

三、创建service的实现类

package swy.plus.springbootaliyunsms.cn.swy.sms.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 lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import swy.plus.springbootaliyunsms.cn.swy.sms.service.SendSmsService;

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

/**
 * Spring-Boot-AliyunSms
 * 2020-07-17 12:00
 * swy.plus.springbootaliyunsms.cn.swy.sms.service.impl
 * 10456
 */
@Service
@Data // lombok的注解
public class SendSmsServiceImpl implements SendSmsService {

    private static final Logger logger = LoggerFactory.getLogger(SendSmsServiceImpl.class);
    // 这里采用 注入的方式传递参数
    @Value("${aliyun.accessKeyID}")
    private String accessKeyID;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;

    @Override
    public boolean sendSms(String phoneNum, String code) {

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyID, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("SignName", "签名名称");
        request.putQueryParameter("PhoneNumbers", phoneNum);
        request.putQueryParameter("TemplateCode", "模板code");

        Map<String, Object> params = new HashMap<>();
        params.put("code", code);

        request.putQueryParameter("TemplateParam", JSON.toJSONString(params));

        try {
            CommonResponse response = client.getCommonResponse(request);
//            System.out.println(response.getData());  // 返回的消息
            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;
    }
}

四、创建controller控制器

package swy.plus.springbootaliyunsms.cn.swy.sms.controller;

import com.aliyuncs.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import swy.plus.springbootaliyunsms.cn.swy.sms.service.SendSmsService;

import java.util.concurrent.TimeUnit;
/**
 * Spring-Boot-AliyunSms
 * 2020-07-17 12:02
 * swy.plus.springbootaliyunsms.cn.swy.sms.controller
 * 10456
 */
@RestController
@CrossOrigin // 跨域支持
public class SendSmsController {

    @Autowired
    private SendSmsService sendSmsService;

    // 注入redis操作模板
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @GetMapping("/sendSms")
    public String sendSms(@RequestParam("phoneNum") String phoneNum) {
        // 获取到操作String的对象
        ValueOperations<String, String> stringR = redisTemplate.opsForValue();

        // 根据手机号进行查询
        String phone = stringR.get(phoneNum);

        // 如果手机号在redis中不存在的话才进行发送验证码操作
        if (StringUtils.isEmpty(phone)) {
            // 生成6位随机数
            String code = String.valueOf(Math.random()).substring(3, 9);
            // 调用业务层接口 发送验证码
            boolean sendSmsFlag = sendSmsService.sendSms(phoneNum, code);
            if (sendSmsFlag) {
                // 发送成功之后往redis中存入该手机号以及验证码 并设置超时时间 5 分钟
                stringR.set(phoneNum, code, 5, TimeUnit.MINUTES);
            }
            return "发送验证码到:" + phoneNum + "成功! " + "Message:" + sendSmsFlag;
        } else {
            return "该手机号:" + phoneNum + " 剩余:" + redisTemplate.getExpire(phoneNum) + "秒后可再次进行发送!";
        }
    }

    @GetMapping("/checkCode/{key}/{code}")
    public String checkCode(@PathVariable("key") String number, @PathVariable("code") String code) {

        // 获取到操作String的对象
        ValueOperations<String, String> stringR = redisTemplate.opsForValue();
        // 根据Key进行查询
        String redisCode = stringR.get(number);
        if (code.equals(redisCode)) {
            return "成功";
        } else {
           return redisCode == null?"请先获取验证码在进行校验!" : "错误";
        }
    }
}

五、请求访问接口

image
image
测试成功


版权声明:本文为weixin_43423306原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。