SpringBoot + redis 整合阿里云短信服务

以前所做的短信服务存储都是基于MySQL数据库 + 定时器来实现的,感觉的有点浪费资源,于是把短信服务基于redis重构了

Redis依赖和Reids工具类:https://blog.csdn.net/weixin_46136492/article/details/112919388

1、Maven依赖

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

2、在resources下创建third.properties

# 短信验证码
sms.getAccessKeyId=***
sms.getAccessSecret=***
# 中文获取的时候,必须设置为utf8格式,不然会乱码
sms.getSignName=***
sms.getTemplateCode=***

3、配置SmsDemo

@Component
// 设置UTF-8编码,不然会中文乱码
@PropertySource(value = "classpath:third.properties", encoding = "UTF-8")
public class SmsDemo {
    @Value("${sms.getAccessKeyId}")
    private String getAccessKeyId;

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

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

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

    public String getGetAccessKeyId() {
        return getAccessKeyId;
    }

    public void setGetAccessKeyId(String getAccessKeyId) {
        this.getAccessKeyId = getAccessKeyId;
    }

    public String getGetAccessSecret() {
        return getAccessSecret;
    }

    public void setGetAccessSecret(String getAccessSecret) {
        this.getAccessSecret = getAccessSecret;
    }

    public String getGetSignName() {
        return getSignName;
    }

    public void setGetSignName(String getSignName) {
        this.getSignName = getSignName;
    }

    public String getGetTemplateCode() {
        return getTemplateCode;
    }

    public void setGetTemplateCode(String getTemplateCode) {
        this.getTemplateCode = getTemplateCode;
    }

    @Override
    public String toString() {
        return "SmsDemo{" +
                "getAccessKeyId='" + getAccessKeyId + '\'' +
                ", getAccessSecret='" + getAccessSecret + '\'' +
                ", getSignName='" + getSignName + '\'' +
                ", getTemplateCode='" + getTemplateCode + '\'' +
                '}';
    }

    /**
     * 简要说明:发送手机验证码
     *
     * @param phone [需要发送验证的手机号码]
     * @param code  [短信码]
     * @return boolean [成功true,失败false]
     */
    public boolean create(String phone, String code) {
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", getSignName);
        request.putQueryParameter("TemplateCode", getTemplateCode);
        request.putQueryParameter("TemplateParam", "{\"code\":" + code + "}");

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

        String res = null;
        try {
            res = client.getCommonResponse(request).getData();
        } catch (ClientException e) {
            e.printStackTrace();
        }

        return res != null && res.contains("OK");
    }
}

4、NoteController前端控制器

/**
 * @author: FSL
 * @introduce: 短信类验证 前端控制器
 * @date: 2021/1/20 16:19
 */
@RestController
@RequestMapping("/system/note")
@ResponseBody
public class NoteController extends BaseController {
    @Resource
    private NoteService noteService;

    /**
     * 简要说明:发送验证码
     *
     * @param phone [手机号]
     * @return String
     */
    @PostMapping("/create")
    public String create(@RequestParam(value = "phone") @Size(min = 11, max = 11) String phone) {
        return noteService.create(phone);
    }

    /**
     * 简要说明:获取手机号验证码
     *
     * @param phone [手机号]
     * @return String
     */
    @PostMapping("/getCode")
    public String getCode(@RequestParam(value = "phone") @Size(min = 11, max = 11) String phone,
                     @RequestParam(value = "code") @Size(min = 6, max = 6) String code
    ) {
        return noteService.isCode(phone, code) ? "true" : noteService.isCode(phone);
    }
}

5、NoteService服务实现类

/**
 * @author: FSL
 * @introduce: 短信类验证 服务实现类
 * @date: 2021/1/20 17:45
 */
@Service
public class NoteService {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private SmsDemo smsDemo;
    private final int lockNum = 5;	// 锁定次数
    private final int time = 15 * 60; // 锁定时间,单位秒

	/**
     * 简要说明:短信错误校验key
     *
     * @param phone [手机号]
     * @return java.lang.String
     */
	public String getCodeError(String phone) {
        return "SMS_CODE_ERROR" + phone;
    }

	/**
     * 简要说明:发送验证码
     *
     * @param phone [手机号]
     * @return java.lang.String
     */
    public String create(String phone) {
        String code = "123456";	// 一般为4位或者6位的随机数

        String r;
        if (isPhone(phone)) {
            r = "当前手机号已锁定,15分钟后自动解锁"; // 这里的锁定时间可以根据key的剩余时间动态获取
        } else {
            String smsKey = "SMS_CODE " + phone;
            redisUtil.setString(smsKey, code, time);

            r =  smsDemo.create(phone, code) ? "发送成功" : "发送失败";
        }
        return r;
    }

	/**
     * 简要说明:判断手机号是否已被锁定
     *
     * @param phone [手机号]
     * @return boolean
     */
    public boolean isPhone(String phone) {
        String errorKey = getCodeError(phone);
        String string = redisUtil.getString(errorKey);
        if (string == null) {
            return false;
        }
        int anInt = Integer.parseInt(redisUtil.getString(errorKey));

        return anInt == lockNum;
    }

	/**
     * 简要说明:判断手机号是否已被锁定
     *
     * @param phone [手机号]
     * @return String
     */
    public String isCode(String phone) {
        if (isPhone(phone)) {
            return "当前手机号已锁定,15分钟后自动解锁";
        }

        String errorKey = getCodeError(phone);
        int anInt = 0;

        if (redisUtil.getString(errorKey) != null) {
            anInt = Integer.parseInt(redisUtil.getString(errorKey));
        }

        int lockError = anInt + 1;
        redisUtil.setString(errorKey, String.valueOf(lockError), time);

        if (lockError == lockNum) {
            return "当前手机号已锁定,15分钟后自动解锁";
        }

        return "你已经连续输错验证码" + lockError + "次,如果再输错" + (lockNum - lockError) + "次,系统自动锁定该手机号,请慎重";
    }

	/**
     * 简要说明:校验验证码是否正确
     *
     * @param phone [手机号]
     * @param code  [手机验证码]
     * @return boolean
     */
    public boolean isCode(String phone, String code) {
        String smsKey = "SMS_CODE" + phone;
        boolean exists = redisUtil.exists(smsKey);

        String codeRedis = redisUtil.getString(smsKey);

        if (exists && code.equals(codeRedis)) {
            redisUtil.delString(getCodeError(phone));
            return true;
        }

        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Little Tomato

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值