废话少数,直入主题。

先开放一个子用户,具有管理短信权限。(AliyunDysmsFullAccess)

https://ram.console.aliyun.com/users

阿里云短信控制台

签名,模板,这些基本的东西先设置一下。

进来idea编程,这里我直接用 SpringBoot 演示。

依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.5.1</version>
    </dependency>
</dependencies>

application.yml 中添加阿里云sms的配置信息

#阿里云短信
aliyun:
  sms:
    regionId: cn-hangzhou 
    keyId: 
    keySecret: 
    templateCode: SMS_198675164
    signName: 小湖学院

regionId:不用改

keyId:开头给予权限的用户,KeyId

keySecret:开头给予权限的用户,keySecret

templateCode:模板的CODE

signName:签名

把上面的配置信息同步到代码中来 新建 config.SmsProperties

@Data
@Component
@ConfigurationProperties(prefix="aliyun.sms")
public class SmsProperties {
    private String regionId;
    private String keyId;
    private String keySecret;
    private String templateCode;
    private String signName;
}

主要的业务代码:我们写到 SmsServiceImpl

package com.xn2001.service;

/**
 * @author 乐心湖
 * @date 2020/7/29 22:45
 **/
@Service
@Slf4j
public class SmsServiceImpl implements SmsService {

    @Autowired
    private SmsProperties smsProperties;

    @Override
    public void send(String mobile, String checkCode) throws ClientException {
        //调用短信发送SDK,创建client对象
        DefaultProfile profile = DefaultProfile.getProfile(
                smsProperties.getRegionId(),
                smsProperties.getKeyId(),
                smsProperties.getKeySecret());
        IAcsClient client = new DefaultAcsClient(profile);

        //组装请求参数
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", smsProperties.getRegionId());
        request.putQueryParameter("PhoneNumbers", mobile);
        request.putQueryParameter("SignName", smsProperties.getSignName());
        request.putQueryParameter("TemplateCode", smsProperties.getTemplateCode());

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

        //将包含验证码的集合转换为json字符串
        Gson gson = new Gson();
        request.putQueryParameter("TemplateParam", gson.toJson(param));

        //发送短信
        CommonResponse response = client.getCommonResponse(request);

        //得到json字符串格式的响应结果
        String data = response.getData();

        //解析json字符串格式的响应结果
        HashMap<String, String> map = gson.fromJson(data, HashMap.class);
        String code = map.get("Code");
        String message = map.get("Message");

        //配置参考:短信服务->系统设置->国内消息设置
        if ("isv.BUSINESS_LIMIT_CONTROL".equals(code)) {
            log.error("短信发送过于频繁 " + "【code】" + code + ", 【message】" + message);
        }

        if (!"OK".equals(code)) {
            log.error("短信发送失败 " + " - code: " + code + ", message: " + message);
        }

    }
}

这里有个 错误码大纲 ,你可以根据官方文档来进行更多自定义的日志处理或者交互体验。(继续if即可)

在调用业余方法之前,我介绍两个工具类。

验证手机号输入是否正确

package com.xn2001.util;

/**
 * 手机号验证工具类
 *
 * @author qy
 * @since 1.0
 */
public class FormUtils {

    /**
     * 手机号验证
     */
    public static boolean isMobile(String str) {
        Pattern p = Pattern.compile("^[1][3,4,5,7,8,9][0-9]{9}$"); // 验证手机号
        Matcher m = p.matcher(str);
        return m.matches();
    }

}

生成随机验证码,可以生成四位或六位

package com.xn2001.util;


/**
 * 获取随机数
 *
 * @author qianyi
 *
 */
public class RandomUtils {

    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;
    }
}

SmsController api接口

package com.xn2001.controller;

/**
 * @author 乐心湖
 * @date 2020/7/29 23:16
 **/
@RestController
@Slf4j
public class SmsController {
    @Autowired
    private SmsService smsService;

    @GetMapping("/send/{mobile}")
    public String send(@PathVariable String mobile) throws ClientException {
        //校验手机号是否合法
        if(StringUtils.isEmpty(mobile) || !FormUtils.isMobile(mobile)) {
            log.error("请输入正确的手机号码 ");
            return null;
        }
        //生成验证码
        String checkCode = RandomUtils.getFourBitRandom();
        //发送验证码
        smsService.send(mobile, checkCode);
        return "短信验证码发送成功";
    }
}

启动,浏览器输入 http://localhost:8080/send/你的手机号

欧克。不出意外应该就能收到短信了。

项目中我们会把这个 手机号:验证码 保存到redis中,设置5分钟后这个key失效。

例如:redisTemplate.opsForValue().set(mobile, checkCode, 5, TimeUnit.MINUTES);

这一步我们就可以后续校验时直接通过redis取出验证码。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!


腾讯云社区邀请各位技术博主加入,福利多多噢!
Last modification:August 10th, 2020 at 02:42 pm
如果觉得我的文章对你有用,请随意赞赏