ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MQ+短信发送(前端vue)+redis

2021-12-07 16:02:02  阅读:139  来源: 互联网

标签:code 短信 String request redis vue MQ user public


文章目录


前言

一、发送验证码的使用

短信发送是电信运营商提供的服务,需要访问对应的接口,不同运营商提供的接口地址肯定不一样,如果直接访问这些接口就需要判断收信息的手机号属于哪个运营商,关键在于这些接口不对个人开放,还要考虑调用短信服务的费用问题
因此目前调用短信业务都是使用第三方企业的短信服务,他们与运营商合作,封装了短信接口,调用方法,而且费用相对便宜
在这里插入图片描述

短信服务(推荐)

注册购买

第一步:云市场搜索短信服务
点击购买,有5条免费使用,测试也会消耗使用次数,用完了在付费购买即可
在这里插入图片描述
找到自己购买的云服务
在这里插入图片描述
可以看到已购买的服务

这里有几项重要信息:AppKey AppSecret AppCode 调用购买的这个短信服务接口时候需要用到,用于确认使用者身份

接口 : 调用该服务时访问的接口
在这里插入图片描述
参考API,编写发送短信工具类

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;

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

/**
 * 测试短信
 */
public class SmsUtilTest {

    public static void main(String[] args) {
        //手机号码
        String mobile = "";
        //验证码
        String code = "";
        //签名ID。(联系客服申请。测试请用:2e65b1bb3d054466b82f0c9d125465e2)
        String smsSignId="";
        //模板ID。(联系客服申请。测试ID请用:908e94ccf08b4476ba6c876d13f084ad,短信内容为 { 验证码:**code**,**minute**分钟内有效,请勿泄漏于他人!})
        String templateId="";
        //应用code  https://market.console.aliyun.com/imageconsole/index.htm?#/bizlist?_k=r5f9m0 查找
        String appCode="";

        //请求连接
        String host = "https://gyytz.market.alicloudapi.com/sms/smsSend";
        //拼装请求体
        Map<String, Object> querys = new HashMap<String, Object>();
        querys.put("mobile", mobile);
        querys.put("param", "**code**:"+code+",**minute**:5");
        querys.put("smsSignId", smsSignId);
        querys.put("templateId", templateId);

        try {
            String result = HttpRequest.post(host)
                    .header(Header.AUTHORIZATION, "APPCODE " + appCode)//头信息,多个头信息多次调用此方法即可
                    .form(querys)//表单内容
                    .timeout(20000)//超时,毫秒
                    .execute().body();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

二、实例

前端Vue

<template>
<div style="text-align:left">
	用户名:<input type="text" class="txt" v-model="user.username" name="username" />3-20位字符,可由中文、字母、数字和下划线组成<br>
	密码  :<input type="password" class="txt" name="password" v-model="user.password"/>6-20位字符,可使用字母、数字和符号的组合,不建议使用纯数字、纯字母、纯符号<br>
	确认密码:<input type="password" class="txt" name="password" v-model="user.repassword"/><br>
	手机号码:<input type="text" class="txt" name="mobile" v-model="user.mobile" />
    <button  @click.prevent="sendSMS" :disabled="smsBtnDisabled">点击发送短信验证码<span v-if="smsBtnDisabled">{{second}}秒</span></button>
    <br>
	验证码:<input type="text"  name="user.code" v-model="user.code"/><br>
	<input type="submit" value="注册" @click="regist()"/>
</div>
</template>

<script>
export default {
    data() {
        return {
            user:{},
            smsBtnDisabled:false,// true 禁用按钮 false不禁用
            second:5,//倒计时秒数
            timer:null//倒计时对象
        }
    },
    methods: {
        async sendSMS(){
            let res = await this.$http.get("http://localhost:10010/user/sendSms?phone="+this.user.mobile)
            // let res = await this.$http.get("/user/sendSms",{params:user.mobile})
            if(res.data.code==0){
                //发送成功
                alert("发送成功")
                //按钮禁用
                this.smsBtnDisabled = true
                //倒计时:每个1s执行某个函数
                this.timer = setInterval(this.daojishi,1000)
            }
        },
        daojishi(){
            //如果second大于0,那second--
            //否则停止倒计时,按钮生效
            if(this.second>0){
                this.second--
            }else{
                //停止倒计时
                clearInterval(this.timer)
                //恢复秒数。给下次使用
                this.second=5
                //按钮恢复
                this.smsBtnDisabled = false
            }
        },
        async regist(){
          try { 
               let res = await this.$http.post("http://localhost:10010/user/reg",this.user)
            if(res.data.code==0){
                alert("注册成功")
                console.log(res)
                this.$router.push("登录页")
            }else{
                alert("注册失败")
            }
            }catch (error) {
                alert("res.msg")
            }
        }
    },
}
</script>

后端
启动类
UserController

@RestController
@RequestMapping("/user")
public class UserController {

//    @Autowired
//    private HttpServletRequest request;
    @Autowired
    private RabbitTemplate rabbitTemplate;
//    RabbitTemplate  rabbitTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @PostMapping
    public BaseResult addUser(@RequestBody User user,
                              @RequestHeader("Authorization") String authorization){
//      String token = request.getHeader("authorization");
        Claims claims = JWTUtil.parseToken(authorization, "user");
        Object userId = claims.get("userId");
        System.out.println("新增的用户信息:"+user);

        return BaseResult.success(null);
    }
    /**
     * 1 产生随机码6位
     * 2 保存到rabbitMQ中
     * 3 保存到redis中
     * 4 返回发送成功
     * @param phone
     * @return
     */
    //

    @GetMapping("/sendSms")
    public BaseResult sendSMS(String phone){

//       1 产生随机码6位
        String code = RandomUtil.code();
        //拼接消息内容
        String msg = phone + "%%%%%%" + code;

//       2 保存到rabbitMQ中
        rabbitTemplate.convertAndSend("sms.queue",msg);

//       3 保存到redis中
        redisTemplate.opsForValue().set(phone,code,1, TimeUnit.MINUTES);
//       4 返回发送成功
        return BaseResult.success("成功");

    }


    @PostMapping("/reg")
    public BaseResult reg(@RequestBody User user){
        String s2 = user.getMobile();
        String s = redisTemplate.opsForValue().get(s2);
        System.out.println(s);
        if (s==null){
            return BaseResult.fail();
        }
        if (user.getCode().equals(s)){
            System.out.println("注册成功,"+user);
            redisTemplate.delete(user.getMobile());
            return BaseResult.success("成功"+user);
        }
        return BaseResult.fail();
    }
}

配置文件bootstrap.yaml

spring:
  datasource:
    url: jdbc:mysql://localhost/数据库表名?useSSL=false
    username: 账户名
    password: 密码
    driver-class-name: com.mysql.jdbc.Driver
  application:
  //服务名
    name: userservice
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        file-extension: yaml
#  rabbitmq:
#    host:# 主机名
#    port: 5672 # 端口
#    virtual-host: / # 虚拟主机
#    username: # 用户名
#    password: # 密码
  redis:
    host: localhost
    port: 6379
    database: 0
    jedis:
      pool:
        max-idle: 8
        min-idle: 0
        max-active: 8
server:
  port: 8000

SmsListener同步redis中的值

@Component
public class SmsListener {

    @RabbitListener(queues = "sms.queue")
    public void listenerWorkQueue1(String msg) throws Exception{

        String[] vals = msg.split("%%%%%%");
        //这里调用短信接口
        AliyunSendSmsUtil.send(vals[0],vals[1]);
        
        System.out.println("sms接收到的消息:【"+msg+"】发送成功");
    }
}

短信接口类

public class AliyunSendSmsUtil {

    /**
     *
     * @param to 手机号码
     * @param code 验证码
     */

    public static void send(String to, String code) {

        String accessKeyId="";
        String accessSecret = "";

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
        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", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", to);
        request.putQueryParameter("SignName", "");
        request.putQueryParameter("TemplateCode", "SMS_85550034");
        request.putQueryParameter("TemplateParam", "{\"code\":\""+code+"\"}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        }
        }

启动类

@SpringBootApplication
public class SmsConsumerApplication {


    @Bean
    public Queue createSmsQueue(){
        return new Queue("sms.queue");
    }
    
    public static void main(String[] args) {
        SpringApplication.run(SmsConsumerApplication.class, args);
    }

}

配置文件application.yml

server:
port: 20000
spring:
rabbitmq:
host: # 主机名
port: 5672 # 端口
virtual-host: / # 虚拟主机
username: # 用户名
password: # 密码

2.项目结构及pom

在这里插入图片描述

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>jwt-common03</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--nacos配置管理依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!--AMQP依赖,包含RabbitMQ-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

</dependencies>

标签:code,短信,String,request,redis,vue,MQ,user,public
来源: https://blog.csdn.net/unclever_behurt/article/details/121770877

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有