SpringBoot实现RabbitMQ+Redis进行用户注册,调用阿里云API发送给短信验证码【在注册时,我这篇文章中没有用JWT,只是简单注册】

实现前提

服务器搭建Redis以及RabbitMQ环境(尽量使用management版本)
在这里插入图片描述在浏览器输入http://(你的服务器地址):15672/#/
默认账号密码为:guest
登陆之后创建队列,我们发送短信,一般都是一对一,所以选择直接模式
使用RabbitMQ给用户发一份验证码,在Redis中存一份,当用户提交注册请求时,两者去匹配
服务器搭建Redis环境(本文省略)
技术栈:SpringBoot2.0、redis、rabbitmq、
在阿里云网站申请短信服务,添加签名,添加模板,创建AccessKey,下载或复制短信发送的JAVA版本的SDK代码

具体代码实现

User层pom文件

 <dependencies>
        <dependency>
            <groupId>com.pure</groupId>
            <artifactId>pure_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>

    </dependencies>

本系统为前后端分离项目
Controller层代码实现:

/**
     * /sendsms/{mobile}
     * 发送手机验证码
     */
    @RequestMapping ( value = "/sendsms/{mobile}", method = RequestMethod.POST )
    public Result sendSms ( @PathVariable String mobile ) {

        userService.sendSms ( mobile );
        return new Result ( true,StatusCode.SMS_SUCCESS );
    }

    /**
     * /register/{code}
     * 注册用户
     */
    @RequestMapping ( value = "/register/{code}", method = RequestMethod.POST )
    public Result register ( @RequestBody User user,@PathVariable String code ) {
        //手机号怎么拿,在填写注册信息的时候,得封装道一个对象中
        //在注册过程中的要去验证手机验证码是否正确,如果缓存中没有,证明是瞎写的
        String checkCodeRedis = (String) redisTemplate.opsForValue ( ).get ( "checkCode_" + user.getMobile ( ) );
        if (checkCodeRedis.isEmpty ( )) {
            return new Result ( false,StatusCode.ERROR );
        }
        if (!checkCodeRedis.equals ( code )){
            return  new Result (  false ,StatusCode.CODE_ERROR );
        }
        userService.add ( user );
        return new Result ( true,StatusCode.ADD_USER_SUCCESS );
    }

两个接口,一个为短信发送,一个为用户注册【注:其中判断验证码的我是写在控制层,这样也可以,也可以写在业务层】
Service层业务实现

  /**
     * 增加,注册用户
     *
     * @param user
     */
    public void add ( User user ) {
        user.setId ( idWorker.nextId ( ) + "" );
        //把判断放在controller层,不管是在业务层还是在控制层,都可以
        user . setFollowcount(0);//关注数
        user . setFanscount(0);//粉丝数
        user.setOnline ( 0L );
        user . setRegdate(new Date());//注册 日期
        user . setUpdatedate(new Date());//更新日期
        user . setLastdate(new Date());//最后 登陆日期

        userDao.save ( user );
    }
//发送手机验证码
//生成六位随机数
        //这里可能会出现一个异常,已解决
        String checkCode = RandomStringUtils.randomNumeric ( 6 );
//这里生成随机六位数,直接使用阿帕奇的common-lang3,代码更简洁

        //给缓存发一份
        redisTemplate.opsForValue ( ).set ( "checkCode_" + mobile,checkCode,5,TimeUnit.MINUTES );

        //用户发一份
        Map < String, String > SmsMap = new HashMap <> ( );
        SmsMap.put ( "mobile",mobile );
        SmsMap.put ( "checkCode",checkCode );
        rabbitTemplate.convertAndSend ( "pure_sms",SmsMap );

        //在控制器输出一份【方便测试】
        System.out.println ( "验证码为:" + checkCode );
        //这个输出是为了更方便测试,具体实施的时候,要删掉,不然不你想干嘛,用户发一份,我这里收到一份,赶紧注册把钱全部给转走??哈哈哈哈这样不行的喔
    }
   

```java
server:
  port: 1008
spring:
  application:
    name: pure-user #指定服务名
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: 
    username: 
    password: 
  jpa:
    database: MySQL
    show-sql: true
  redis:
    host: 192.168.232.134
  rabbitmq:
    host: 192.168.232.134

wode
我的这是微服务项目
前面的注册,短信发送的控制业务写完了
现在我们需要写短信微服务
所需pom文件

 <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>com.aliyun</groupId>-->
<!--            <artifactId>dysmsapi20170525</artifactId>-->
<!--            <version>2.0.1</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>tea-openapi</artifactId>
            <version>0.0.11</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>tea-console</artifactId>
            <version>0.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>tea-util</artifactId>
            <version>0.2.10</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>tea</artifactId>
            <version>[1.0.3, 2.0.0)</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.0.6</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>

前面我们在阿里云下载了一个SDK工具类,我的和那个有点区别
我两个都拿出来,参考者用哪个都行

package com.pure.sms.utils;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;

import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 短信工具类
 * @author pure
 *
 */
@Component
public class SmsUtil {

    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";

    @Autowired
    private Environment env;

    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)

    /**
     * 发送短信
     * @param mobile 手机号
     * @param template_code 模板号
     * @param sign_name 签名
     * @param param 参数
     * @return
     * @throws ClientException
     */
    public SendSmsResponse sendSms( String mobile,String template_code,String sign_name,String param) throws ClientException {
        String accessKeyId =env.getProperty("aliyun.sms.accessKeyId");
        String accessKeySecret = env.getProperty("aliyun.sms.accessKeySecret");
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(mobile);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(sign_name);
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(template_code);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam(param);
        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");
        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        request.setOutId("yourOutId");
        //hint 此处可能会抛出异常,注意catch

        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        return sendSmsResponse;
    }

    public QuerySendDetailsResponse querySendDetails( String mobile,String bizId) throws ClientException {
        String accessKeyId =env.getProperty("accessKeyId");
        String accessKeySecret = env.getProperty("accessKeySecret");
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象
        QuerySendDetailsRequest request = new QuerySendDetailsRequest();
        //必填-号码
        request.setPhoneNumber(mobile);
        //可选-流水号
        request.setBizId(bizId);
        //必填-发送日期 支持30天内记录查询,格式yyyyMMdd
        SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
        request.setSendDate(ft.format(new Date()));
        //必填-页大小
        request.setPageSize(10L);
        //必填-当前页码从1开始计数
        request.setCurrentPage(1L);
        //hint 此处可能会抛出异常,注意catch
        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
        return querySendDetailsResponse;
    }
}

上面的是我的工具类,下面的是阿里云下载的SDK

// This file is auto-generated, don't edit it. Thanks.
package com.aliyun.sample;

import com.aliyun.tea.*;
import com.aliyun.dysmsapi20170525.*;
import com.aliyun.dysmsapi20170525.models.*;
import com.aliyun.teaopenapi.*;
import com.aliyun.teaopenapi.models.*;
import com.aliyun.teaconsole.*;
import com.aliyun.teautil.*;

public class Sample {

    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    public static void main(String[] args_) throws Exception {
        java.util.List<String> args = java.util.Arrays.asList(args_);
        com.aliyun.dysmsapi20170525.Client client = Sample.createClient("ACCESS_KEY_ID", "ACCESS_KEY_SECRET");
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        SendSmsResponse resp = client.sendSms(sendSmsRequest);
        com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp)));
    }
}







还有相对应的pom
 <dependencies>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>dysmsapi20170525</artifactId>
      <version>2.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea-openapi</artifactId>
      <version>0.0.11</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea-console</artifactId>
      <version>0.0.1</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea-util</artifactId>
      <version>0.2.10</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>tea</artifactId>
      <version>[1.0.3, 2.0.0)</version>
    </dependency>
  </dependencies>


SMS服务结构如上
别忘了配置文件

server:
  port: 1009
spring:
  application:
    name: pure-sms #指定服务名
  rabbitmq:
    host: 192.168.232.134
aliyun:
  sms:
    accessKeyId:这里是你阿里云创建的accessKeyId
    accessKeySecret: 还有这个
    template_code:这是是你的阿里云短信模板
    sign_name:这是你的阿里云短信签名

这些弄好之后,就可以写MQ的队列监听器了,直接上代码

package com.pure.sms.listener;

import com.aliyuncs.exceptions.ClientException;
import com.pure.sms.utils.SmsUtil;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author 刘乐锋
 * @create 2021/3/7 21:37
 */
//消息队列监听器
@Component
@RabbitListener ( queues = "pure_sms" ) //让它是消费者
public class SmsListener {

    @Autowired
    private SmsUtil smsUtil;

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

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

    @RabbitHandler
    public  void  executeSms( Map<String,String> map ){
        String mobile = map.get ( "mobile" );
        String checkCode= map.get ( "checkCode" );
        System.out.println ("手机号:"+map.get ( "mobile" ) );
        System.out.println ("验证码:"+map.get ("checkCode"  ) );
        try {
            smsUtil.sendSms ( mobile, template_code,sign_name,"{\"checkcode\": \""+checkCode+"\"}");
        } catch (ClientException e) {
            e.printStackTrace ( );
        }
    }
}

两个输出可以删除,这里方便测试才写
之后就可以运行实现了,记得保证阿里云账户有钱,10快就可以玩好久,土豪随意

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,以下是我对大众商城的设计思路: 1. 架构设计 大众商城的整体架构采用微服务架构设计,将各个模块拆分为不同的服务,以实现服务之间的解耦,减小维护成本。使用Spring Cloud作为微服务框架,采用Eureka作为服务注册心,Zuul作为网关来提供负载均衡、流量限制等功能。 2. 数据库设计 考虑到大众商城数据量较大,我们选用关系型数据库MySQL进行数据存储,采用主从复制技术来实现数据的高可用性。对于数据安全,我们使用阿里云RDS提供的数据加密技术和数据备份功能,确保数据的可靠性和安全性。 3. 技术选型 后端技术选用Spring Boot作为基础框架,使用MyBatis实现ORM映射;前端技术选用Bootstrap框架实现响应式布局,使用Thymeleaf作为模板引擎,通过AJAX技术实现数据的异步加载和交互。 消息队列技术选用RabbitMQ实现异步消息传递,同利用RabbitMQ自带的延迟消息功能来解决消息的定发送问题。 4. 缓存方案 由于大众商城对数据的访问比较频繁,所以我们在架构加入了Redis缓存,通过对常用数据的缓存来提升系统的响应速度和性能。 5. 安全性 系统安全方面,我们采用JWT令牌的方式实现用户登录和认证,同对敏感数据采用AES加密算法进行加密,保证系统的数据安全性和用户隐私保护。 以上是大众商城的设计思路,希望能对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值