springboot发送短信验证码

学习目标:

  • 阿里云短信服务

准备工作:

  1. 注册阿里云账户
  2. 开通短信服务
  3. 申请签名和模板
  4. 拿到AccessKey

大概说一下测试和申请流程,输入https://www.aliyun.com/进入官网,然后注册账号,直接在搜索框输入短信服务就能找到,进入控制台,找到国内消息,申请签名和模板,
springboot发送短信验证码_第1张图片
在这里插入图片描述
AccessKey:在右上角头像哪里
springboot发送短信验证码_第2张图片

申请大概需要几个小时,个人用户一般很难通过,我个人申请被驳回很多次,最后用域名备案才通过

开始编写代码:

第一步先导入依赖

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

第二步:在项目yml文件中配置阿里云短信的秘钥,秘钥在上面AccessKey管理可以拿到

aliyun:
  sms:
    regionId: default
    accessKeyId: xxxxxxxxxxxxxxxxxxxxxxx
    secret: xxxxxxxxxxxxxxxxxxxxxxx

第三步:去读取配置文件的参数秘钥,InitializingBean接口为bean提供了属性初始化后的处理方法

@Component
public class ConstantPropertiesUtils implements InitializingBean {

    @Value("${aliyun.sms.regionId}")
    private String regionId;

    @Value("${aliyun.sms.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.sms.secret}")
    private String secret;

    public static String REGION_Id;
    public static String ACCESS_KEY_ID;
    public static String SECRECT;

    @Override
    public void afterPropertiesSet() throws Exception {
        REGION_Id=regionId;
        ACCESS_KEY_ID=accessKeyId;
        SECRECT=secret;
    }
}

什么是验证码呢,就是后台随机生成的一段数字,为了方便就写了一个工具类获取验证码

package com.example.shiro.sys.utlis.smsSend;

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

/**
 * @author szm
 * @create 2022-03-31 18:31
 */
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来获取验证码,我这里还整合redis缓存,方便后面做验证码的有效期和校验,不整合redis也不影响发送验证码

/**
     * 发送手机验证码
     */
    @GetMapping("/getCode/{phone}")
    public R getCode(@PathVariable String phone){
        //先从redis获取验证码,如果获取到就返回ok
        //key 手机号 value 验证码
        String code =(String) redisUtil.get(phone);
        if(!StringUtils.isEmpty(code)){
            return R.ok();
        }
        //如果redis获取不到,生成验证码,通过整合短信服务进行发送
        code = RandomUtil.getFourBitRandom();
        //调用service方法,通过整合短信服务进行发送
        boolean isSend = msgSendService.send(phone,code);
        //生成验证码放到redis里面,设置有效时间
        if(isSend){
            redisUtil.set(phone,code, 120);
            return R.ok();
        }else{
            return R.error("发送短信失败!!!");
        }
    }

直接看业务层具体的实现

 @Override
    public boolean send(String phone, String code) {
        //判断手机号是否为空
        if(StringUtils.isEmpty(phone)){
            return false;
        }
        //整合阿里云短信服务
        //设置相关参数
        DefaultProfile profile = DefaultProfile.
                getProfile(ConstantPropertiesUtils.REGION_Id,
                        ConstantPropertiesUtils.ACCESS_KEY_ID,
                        ConstantPropertiesUtils.SECRECT);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        //request.setProtocol(ProtocolType.HTTPS);
        //这些参数都是写死的 不要改变
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");

        //手机号
        request.putQueryParameter("PhoneNumbers", phone);
        //签名名称
        request.putQueryParameter("SignName", "这里写你开通短信的签名");
        //模板code
        request.putQueryParameter("TemplateCode", "模板code");
        //验证码  使用json格式   {"code":"123456"}
        Map<String,Object> param = new HashMap();
        param.put("code",code);
        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;
    }

最后看能不能收到短信验证码,我配置了swagger-ui进行测试
在这里插入图片描述
springboot发送短信验证码_第3张图片

成功接收到,实现也很简单,代码复制就能使用

你可能感兴趣的:(intellij-idea,java,spring,boot,后端)