谷粒教育--阿里云短信服务(8)

阿里云短信服务

新建短信微服务

微服务结构如下

在这里插入图片描述

配置文件yml

spring:
  application:
    name: message-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatisdemo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=true&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  redis:
    host: 192.168.0.113
    port: 6379
    database: 0
    timeout: 18000000
    lettuce:
      pool:
        max-active: 20
        max-wait: -1 #最大阻塞时间 负数表示没有限制
        max-idle: 5
        min-idle: 0
server:
  port: 8006

依赖管理

  <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.1</version>
        </dependency>

        <!--        fastjson  可以把对象等格式快速转换成json格式-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>

开通阿里云短信服务

阿里云短信服务文档
在这里插入图片描述

添加签名管理与模板管理

(1) 添加模板
在这里插入图片描述
(2)添加签名管理
在这里插入图片描述

编写发送短信接口

编写Controller,根据手机号发送短信

业务逻辑
为了避免重复发送短信,利用redis缓存将发送的验证码存于redis中并设置过期时间。

如果缓存中存在则不发送短信,若缓存中验证码code不存在或者过期了,则继续发送短信。

缓存中存储的方式 KEY(phoneNumber)--Value(code)手机号--验证码
1、 传入手机号,判断缓存中是否存在验证码code且判断是否为空

	若存在且不为空,直接返回 return R.ok(); 不执行任何其他操作
	
2、 若缓存中不存在,则在后端生成验证码并将验证码传给阿里云具体过程如下
	
	1、 后端生成验证码可以生成四位、六位或任意位数,在这里封装一个产生四位随机数的工具类
	2、  校验手机号格式是否正确,不正确直接返回
	3、 创建阿里云客户端,设置上传相关参数
	4、 设置手机号、申请到的签名名称以及模板编号
	5、 设置后端生成好的验证码,注意需要传入JSON格式,将String类型转成Json格式后再传入
	6、 发送请求,返回请求是否成功结果 true/false
	
3、 判断是否发送成功

	如果发送成功则将验证码以 KEY(phoneNumber)--Value(code)存在缓存中并返回 return R.ok().message("短信发送成功");
	如果发送失败,则返回  return R.error().message("短信发送失败");
	
随机数工具类
package com.guli.common.utils;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

/**
 * 获取随机数
 *
 * 
 *
 */
public class RandomUtil {

	private static final Random random = new Random();

	private static final DecimalFormat fourdf = new DecimalFormat("0000");

	private static final DecimalFormat sixdf = new DecimalFormat("000000");

	public static String getFourBitRandom() {
		return fourdf.format(random.nextInt(10000));
	}

	public static String getSixBitRandom() {
		return sixdf.format(random.nextInt(1000000));
	}

	/**
	 * 给定数组,抽取n个数据
	 * @param list
	 * @param n
	 * @return
	 */
	public static ArrayList getRandom(List list, int n) {

		Random random = new Random();

		HashMap<Object, Object> hashMap = new HashMap<Object, Object>();

		// 生成随机数字并存入HashMap
		for (int i = 0; i < list.size(); i++) {

			int number = random.nextInt(100) + 1;

			hashMap.put(number, i);
		}

		// 从HashMap导入数组
		Object[] robjs = hashMap.values().toArray();

		ArrayList r = new ArrayList();

		// 遍历数组并打印数据
		for (int i = 0; i < n; i++) {
			r.add(list.get((int) robjs[i]));
			System.out.print(list.get((int) robjs[i]) + "\t");
		}
		System.out.print("\n");
		return r;
	}
}

Controller代码实现
package com.doubleStrong.online.controller;

import com.doubleStrong.online.service.MessageService;
import com.guli.common.constants.R;
import com.guli.common.utils.RandomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Double strong
 * @date 2020/3/28 17:52
 */
@RestController
@RequestMapping("/eduMessage/msg")
@CrossOrigin
public class MessageController {

    @Autowired
    private MessageService messageService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;
//    发送短信的方法
//    后台接收手机号,通过阿里云短信服务实现
    @GetMapping("/send/{phoneNumber}")
    public R sendMessage(@PathVariable("phoneNumber") String phoneNumber)
    {
        //        判断缓存中是否有code,没过期就存在,就直接从缓存中拿code
        String code = redisTemplate.opsForValue().get(phoneNumber);
//        拿到code之后判断是否为空
        if (!StringUtils.isEmpty(code))
        {
            return R.ok();
        }
//        这个四位验证码由后端采用随机数生成,你想生成几位生成几位
//        在这里用四位随机数
        String code1 = RandomUtil.getFourBitRandom();
//        将生成的四位随机数传给阿里云
        Map<String,Object> param=new HashMap<>();
        param.put("code",code1);
//        将code以map集合的形式发给阿里云
    Boolean Success=  messageService.send(param,phoneNumber,"SMS_186945759");
    if(Success==true)
    {
//        如果发送成功,就把把redis成功的验证码放到redis缓存中,并且设置该缓存的有效时间5分钟
        redisTemplate.opsForValue().set(phoneNumber,code1,5, TimeUnit.MINUTES);
        return R.ok().message("短信发送成功");
    }
    else
    {
        return R.error().message("短信发送失败");
    }
    }
}

ServiceImpl代码实现
package com.doubleStrong.online.service.Impl;

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.doubleStrong.online.service.MessageService;
import com.guli.common.constants.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import java.util.Map;

/**
 * @author Double strong
 * @date 2020/3/28 17:54
 * 将电话号码和四位的验证码发送给阿里云
 * 由阿里云根据电话号码发送后端生成的code
 *
 * 如何设置验证码分钟有效
 * 利用redis过期时间,解决验证码过期时间
 * 实现方法
 * 每次发送成功之后,把验证码存放在redis中,并设置过期时间
 *
 */
@Service
public class MessageServiceImpl implements MessageService {

//    用redis模板来存放code,并设置过期时间
//    <String,String> <phone,code>的键值对模板

//    五分钟之内有效的话,如果有效直接从缓冲中获取而不用重复调用,

    @Override
    public Boolean send(Map<String, Object> param, String phoneNumber,String templateCode) {


//        判断手机号码是否为空,严格的来说要判断手机号码格式是否正确
        if(StringUtils.isEmpty(phoneNumber)) return false;

//        (regionId, accessKey, accessSecret)
        DefaultProfile profile=DefaultProfile.getProfile("default", "****************", "*******************");
        //        创建一个客户端

        //默认设置 设置相关参数
        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("PhoneNumbers", phoneNumber);
//        设置签名名称 (我申请的签名的名称)
        request.putQueryParameter("SignName", "谷粒在线教育验证码功能");
//        申请的模板编号
        request.putQueryParameter("TemplateCode", templateCode);
//        加上我的验证码
//          要求传入的验证码是json格式 {"code": "asdassss..."},  JSONObject.toJSONString(param)就是转换成json字符串格式
        request.putQueryParameter("TemplateParam",JSONObject.toJSONString(param));
//

        try {
//           最终发送请求
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            return response.getHttpResponse().isSuccess();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return false;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值