springboot实现短信发送验证码及消息队列发送注册成功短信

  • Post author:
  • Post category:其他


需要

源码

小伙伴可以到微信小程序:”

MINIIT资源库

“获取,作者承诺免费

PS:在编写功能之前,需要得到阿里云短信服务API;

使用消息队列(mq)可以将主业务和副业务分离,主业务是用户注册,注册成功通知是副业务,将主业务和副业务分离

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5ZOGbGU=,size_20,color_FFFFFF,t_70,g_se,x_16

application.yml

spring:
  redis:
    host: 填入自己虚拟机IP #linuxIP
    port: 填入自己Redis端口 #端口
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springbootregisterlogin?serverTimezone=UTC
    username: root
    password: 123456
    default-encoding: UTF-8 #编码字符集
  rabbitmq:
    host: 填入自己虚拟机IP #linuxIP
    port: 填入自己rabbitmq端口 #rabbitmq端口,默认5672
    username: 自己的用户名 #用户名
    password: 自己的密码 #密码
    template:
      exchange: mq.user.exchange #交换机
      retry:
        initial-interval: 1000
        max-interval: 10000
        multiplier: 2
        enabled: true
    publisher-confirms: true
aliyun:
  accessKeyId: 填写自己的短信服务ID #短信服务ID
  accessKeySecret: 填写短信服务授权码 #短信服务授权码
  signName: 填写短息服务名称 #短息服务名称
  templateCode: 填写自己的发送短信模板编号 #发送短信模板编号


mybatis:
  configuration:
    map-underscore-to-camel-case: true #开启驼峰映射

User.java

package com.doll.springbootregisterlogin.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Integer id; //id
    private String phone; // 电话
    private String password; //密码
    private String salt; //盐值
    private String confirmCode; //确认码/验证码
}

UserDto.java

package com.doll.springbootregisterlogin.dto;

import lombok.Data;

@Data
public class UserDto {

    private String phone;
    private String email;

}

MsgServiceImpl.java

package com.doll.springbootregisterlogin.service.impl;

import com.alibaba.fastjson.JSON;
import com.doll.springbootregisterlogin.constants.Constants;
import com.doll.springbootregisterlogin.pojo.User;
import com.doll.springbootregisterlogin.service.MsgService;
import com.doll.springbootregisterlogin.utils.NumberUtil;
import com.doll.springbootregisterlogin.utils.SmsUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class MsgServiceImpl implements MsgService {
    @Resource
    private SmsUtil smsUtil;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 发送短信验证码并存入redis
     * @param user
     */
    @Override
    public void sendVerifyCode(User user) {
        String code = NumberUtil.generateCode(6);//生成验证码
        Map<String,String> map=new HashMap<>();
        map.put("code",code);
        smsUtil.send(user.getPhone(), JSON.toJSONString(map));//发送验证码
        String key = Constants.VERIFY_CODE_PREFIX + user.getPhone();
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);//验证码存入redis
    }

    /**
     * 读取redis验证码并判断输入验证码
     * @param user
     * @return
     */
    @Override
    public Map<String, String> doVerification(User user) {
        Map<String,String> resultMap=new HashMap<>();
        Object VerificationCode = redisTemplate.opsForValue().get(Constants.VERIFY_CODE_PREFIX +user.getPhone());
        if(user.getConfirmCode().equals(VerificationCode)){
            resultMap.put("code","200");
        }else {
            resultMap.put("code","401");
        }
        return resultMap;
    }


}

UserServiceImpl.java

package com.doll.springbootregisterlogin.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.doll.springbootregisterlogin.constants.Constants;
import com.doll.springbootregisterlogin.dto.UserDto;
import com.doll.springbootregisterlogin.mapper.UserMapper;
import com.doll.springbootregisterlogin.pojo.User;
import com.doll.springbootregisterlogin.service.MsgService;
import com.doll.springbootregisterlogin.service.UserService;
import com.doll.springbootregisterlogin.utils.BeanCopyUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private MsgService msgService;
    @Resource
    private RedisTemplate<String,String> redisTemplate;
    @Resource
    private AmqpTemplate amqpTemplate;
    
    @Override
    public Map<String, Object> createByMessage(User user) {
        Map<String,Object> resultMap=new HashMap<>();
        //盐值
        String salt= RandomUtil.randomString(6);
        //加密密码:原始密码+盐值
        String md5Pwd= SecureUtil.md5(user.getPassword()+salt);
        String key = Constants.VERIFY_CODE_PREFIX + user.getPhone();
        //初始化账号信息
        user.setPhone(user.getPhone());
        user.setSalt(salt);
        user.setPassword(md5Pwd);
        //判断短信验证是否正确,正确则调用doVerification()方法,将注册信息存入数据库,并删除redis中验证码,将电话信息写入MQ
        Map<String, String> result = msgService.doVerification(user);
        if (result.get("code").equals("200")){
            int i = userMapper.insertUser(user);
            System.out.println("i---------->"+i);
            if(i==1){
                resultMap.put("code",200);
                redisTemplate.delete(key);//验证成功删除redis中验证码
                //将用户信息写入MQ
                UserDto userDto=new UserDto();
                BeanCopyUtil.copyProperties(user,userDto);
                String message = JSON.toJSONString(userDto);
                amqpTemplate.convertAndSend("user.insert", message);
            }else {
                resultMap.put("code",400);
            }
        }else if (result.get("code").equals("401")){
            resultMap.put("code",401);
        }
        else {
            resultMap.put("code",400);
        }
        return resultMap;
    }
}

Usercontroller.java

package com.doll.springbootregisterlogin.controller;

import com.doll.springbootregisterlogin.pojo.User;
import com.doll.springbootregisterlogin.service.MsgService;
import com.doll.springbootregisterlogin.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private MsgService msgService;

    
    /**
     * 发送短信验证码
     * @param user
     * @return
     */
    @PostMapping("sendVerificationCode")
    public Map<String,Object> sendVerificationCode(User user){
        Map<String,Object> resultMap=new HashMap<>();
        msgService.sendVerifyCode(user);
        resultMap.put("code",200);//发送成功返回成功代码
        return resultMap;
    }


    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping("createByMessage")
    public Map<String,Object> createByMessage(User user){
        System.out.println("已进createByMessage"+user.getPhone());
        return userService.createByMessage(user);
    }
}

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5ZOGbGU=,size_20,color_FFFFFF,t_70,g_se,x_16

注册成功将手机号写入消息队列

application.yml

aliyun:
  accessKeyId: 填自己的 #短信服务ID
  accessKeySecret: 填自己的 #短信服务授权码
  signName: 填自己的 #短信服务名称
  templateCode: 填自己的 #短信服务模板
server:
  port: 8082 #tomcat端口
spring:
  rabbitmq:
    host: 填自己linuxIp# linuxIp
    port: 填自己的rabbitmq端口 #rabbitmq端口
    username: 用户名 #用户名
    password: 密码 #密码

SmsUtil.java(发送短信方法)

package com.doll.utils;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.teaopenapi.models.Config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "aliyun")
@Data
public class SmsUtil {

    private String accessKeyId;
    private String accessKeySecret;
    private String signName;
    private String templateCode;

    public void send(String phone, String code) {
        Config config = new Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        Client client = null;
        try {
            client = new Client(config);
        } catch (Exception e) {
            //throw new BasicException(ExceptionEnum.ALIYUN_CREATE_CLIENT_FAIL);
        }
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(phone)
                .setSignName(signName)
                .setTemplateCode(templateCode)
                .setTemplateParam(code);
        try {
            client.sendSms(sendSmsRequest);
        } catch (Exception e) {
            //throw new BasicException(ExceptionEnum.CALL_SMS_API_FAIL);
        }
    }
}

MsgListener.java(监听mq,监听到手机号就调用执行发送短信通知注册成功)

package com.doll.liseners;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.doll.utils.SmsUtil;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Component
public class MsgListener {


    @Resource
    private SmsUtil smsUtil;


    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value = "msg.queue"),
                    exchange = @Exchange(value = "mq.user.exchange",type = ExchangeTypes.TOPIC),
                    key = {"user.insert"}
            )
    )
    public void sendMsg(String message){
        System.out.println("msg===========>"+message);
        JSONObject jsonObject = JSONObject.parseObject(message);
        String phone = jsonObject.getString("phone");
        Map<String, String> map = new HashMap<>();
        map.put("code",phone);
        String value = JSON.toJSONString(map);
        smsUtil.send(phone,value);
    }
}

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5ZOGbGU=,size_20,color_FFFFFF,t_70,g_se,x_16



版权声明:本文为qq_51001054原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。