0
点赞
收藏
分享

微信扫一扫

短信服务和注册功能

1. 注册功能分析  78

短信服务和注册功能_spring

短信服务和注册功能_spring_02

2. 验证手机号是否注册 79

短信服务和注册功能_apache_03

2.1 验证手机号格式   79

操作micr-common

CommonUtil

/*手机号格式 true:格式正确;false不正确*/
    public static boolean checkPhone(String phone){
        boolean flag = false;
        if( phone != null && phone.length() == 11 ){
            //^1[1-9]\\d{9}$
            flag = Pattern.matches("^1[1-9]\\d{9}$",phone);
        }
        return flag;


    }

添加枚举类  79

短信服务和注册功能_spring_04

2.2 业务接口  80

操作micr-api

UserService

package com.bjpowernode.api.service;

import com.bjpowernode.api.model.User;

//用户操作的业务接口  80
public interface UserService {
    
    //根据手机号查询数据  80
    User queryByPhone(String phone);
}

2.3 业务接口实现类

micr-dataservice

UserServiceImpl

package com.bjpowernode.dataservice.service;

import com.bjpowernode.api.model.User;
import com.bjpowernode.api.service.UserService;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.dataservice.mapper.UserMapper;
import org.apache.dubbo.config.annotation.DubboService;

import javax.annotation.Resource;

//用户操作的实现类   80

@DubboService(interfaceClass = UserService.class,version = "1.0")
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    //根据手机号查询数据  80
    @Override
    public User queryByPhone(String phone) {
        User user = null;
        if(CommonUtil.checkPhone(phone)){
            user = userMapper.selectByPhone(phone);
        }
        return null;
    }
}

2.4 在mapper中定义方法  80

micr-dataservice

UserMapper

//根据手机号查询数据  80
    User selectByPhone(String phone);

2.5 编写sql

micr-dataservice

UserMapper.xml

<!--根据手机号查询数据  80-->
  <select id="selectByPhone" resultType="com.bjpowernode.api.model.User">
    select <include refid="Base_Column_List"></include>
    from u_user
    where phone = #{phone}
  </select>

2.4 消费者 UserContorller  80

操作micr-web

BaseController

//用户操作  80
    @DubboReference(interfaceClass = UserService.class,version = "1.0")
    protected UserService userService;

UserController   80

package com.bjpowernode.front.controller;


import com.bjpowernode.api.model.User;
import com.bjpowernode.common.enums.RCode;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.front.view.RespResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

//有关用户的操作  79
@Api(tags = "用户功能")
@RestController
@RequestMapping("/v1/user")
public class UserContorller extends BaseController{


    //验证手机号是否注册  79
    @ApiOperation(value = "手机号是否注册过",notes = "在注册功能中,判断手机号是否可以注册")
    @ApiImplicitParam(name = "phone",value = "手机号")
    @GetMapping("/phone/exists")
    public RespResult phoneExists(@RequestParam("phone") String phone){
        RespResult result = new RespResult();
        result.setRCode(RCode.PHONE_EXISTS);
        //检查请求参数手机号是否符合要求  79
        if(CommonUtil.checkPhone(phone)){
            //可以执行逻辑,查询数据库,调用数据服务
            User user = userService.queryByPhone(phone);
            if (user==null){
                //可以注册
                result = RespResult.ok();
            }
        }else {
            result.setRCode(RCode.PHONE_FORMAT_ERR);
        }

        return result;
    }
}

测试   81

使用postman

http://localhost:8000/api/v1/user/phone/exists

短信服务和注册功能_apache_05

短信服务和注册功能_json_06

3. 发送短信  82-85

这里我们使用京东万象的短信服务

资料我放在了E:\java学习\盈利宝\资料\资料\07-短信验证码

短信服务和注册功能_spring_07

3.1加入依赖   85

micr-common

pom.xml

短信服务和注册功能_spring_08

<!--    加入commons-lang3依赖  85-->
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!--87-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

        <!--fastjson   87-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>

    </dependencies>

3.2 配置文件   85

micr-web

application.yml

短信服务和注册功能_json_09

#短信配置   85
jdwx:
  sms:
    url: https://way.jd.com/chuangxin/dxjk
    appkey: 3680fa919b771148da626bbcbd459475
    content: 【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人

3.3 京东万象短信配置类   85

JdwxSmsConfig

package com.bjpowernode.front.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

//京东万象短信配置类  85
@Component
@ConfigurationProperties(prefix = "jdwx.sms")
public class JdwxSmsConfig {
    private String url;
    private String appkey;
    private String content;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getAppkey() {
        return appkey;
    }

    public void setAppkey(String appkey) {
        this.appkey = appkey;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

3.4 短信业务接口   86

micr-web

SmsService

package com.bjpowernode.front.service;

//短信服务的业务接口   86
public interface SmsService {
    //发送短信   86
    boolean sendSms(String phone);
}

3.5 短信业务接口的实现类   86-87

micr-common

短信服务和注册功能_spring_10

micr-web

SmsCodeRegisterImpl   87

package com.bjpowernode.front.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.front.config.JdwxSmsConfig;
import com.bjpowernode.front.service.SmsService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * 短信服务的业务接口实现类   86
 * 注册发送短信验证码
 */

@Service
public class SmsCodeRegisterImpl implements SmsService {

    //注入StringRedisTemplate   89
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private JdwxSmsConfig smsConfig;

    @Override
    public boolean sendSms(String phone) {

        boolean send = false;

        // 设置短信内容,生成随机数
        String random  = RandomStringUtils.randomNumeric(4);
        System.out.println("注册验证码的随机数 random="+random);

        //更新content中的  %s   【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人
        String content  = String.format(smsConfig.getContent(), random);

        //使用HttpClient发送 get 请求 给第三方。87
        CloseableHttpClient client = HttpClients.createDefault();

        //https://way.jd.com/chuangxin/dxjk?mobile=13568813957&content=
        //【创信】你的验证码是:5873,3分钟内有效!&appkey=您申请的APPKEY
        String url = smsConfig.getUrl()+"?mobile="+phone
                        +"&content=" + content
                        +"&appkey="+smsConfig.getAppkey();
        //创建get方式发送   87
        HttpGet get  = new HttpGet(url);

        try{
            //发送
            CloseableHttpResponse response = client.execute(get);
            //发送成功
            if( response.getStatusLine().getStatusCode() == HttpStatus.SC_OK ){

                //得到返回的数据,json   87
//                String text = EntityUtils.toString(response.getEntity());
                //因为发送短信过期了,所以我们为了测试就改造一下
                //模拟成功 返回的数据  88
                String text="{\n" +
                        "    \"code\": \"10000\",\n" +
                        "    \"charge\": false,\n" +
                        "    \"remain\": 1305,\n" +
                        "    \"msg\": \"查询成功\",\n" +
                        "    \"result\": {\n" +
                        "        \"ReturnStatus\": \"Success\",\n" +
                        "        \"Message\": \"ok\",\n" +
                        "        \"RemainPoint\": 420842,\n" +
                        "        \"TaskID\": 18424321,\n" +
                        "        \"SuccessCounts\": 1\n" +
                        "    }\n" +
                        "}";
                //解析json   87
                if(StringUtils.isNotBlank(text)){
                    // fastjson   87
                    //将得到的数据 转为json对象
                    JSONObject jsonObject = JSONObject.parseObject(text);
                    if("10000".equals(jsonObject.getString("code"))){ //第三方接口调用成功
                        //读取result中的key:ReturnStatus
                        if("Success".equalsIgnoreCase( //equalsIgnoreCase忽略大小写的比较字符串
                                //因为result是json,所以要得到他就用getJSONObject
                                jsonObject.getJSONObject("result").getString("ReturnStatus"))){
                            //短信发送成功
                            send  = true;

                            //把短信验证码,存到redis   89
                            String key = RedisKey.KEY_SMS_CODE_REG + phone;
                            stringRedisTemplate.boundValueOps(key).set(random,3 , TimeUnit.MINUTES);
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return send;
    }
}

3.6 controller 87-89

micr-common

短信服务和注册功能_apache_11

micr-web

SmsController  89

package com.bjpowernode.front.controller;

import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.common.enums.RCode;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.front.service.SmsService;
import com.bjpowernode.front.view.RespResult;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

//短信服务  85
@Api(tags = "短信业务")
@RestController
@RequestMapping("/v1/sms")
public class SmsController extends BaseController{

    @Resource
    private SmsService smsService;

    //发送短信验证码   85
    @GetMapping("/code/register")
    public RespResult sendCodeRegister(@RequestParam String phone){
        RespResult result = RespResult.fail();

        if(CommonUtil.checkPhone(phone)){//手机号格式正确,可以发送短信  89
            //判断redis中是否有这个手机号的验证码   89
            String key  = RedisKey.KEY_SMS_CODE_REG + phone;
            if(stringRedisTemplate.hasKey(key)){
                result = RespResult.ok();
                result.setRCode(RCode.SMS_CODE_CAN_USE);
            } else {
                boolean isSuccess = smsService.sendSms(phone);
                if( isSuccess ){
                    result = RespResult.ok();
                }
            }
        }else {
            result.setRCode(RCode.PHONE_FORMAT_ERR);
        }


        return result;
    }
}

4. 手机号的用户注册   90

短信服务和注册功能_json_12

4.1  业务接口   91

micr-api

UserService

//用户注册   91
    int userRegister(String phone, String password);

4.2 业务接口实现类   91

4.2.1 密码的盐   91

micr-dataservice

短信服务和注册功能_json_13

4.2.2添加记录和获取主键值   91

在UserMapper中定义方法91

//添加记录和获取主键值   91
    int insertReturnPrimaryKey(User user);

编写sql   91

LAST_INSERT_ID() 时获取你刚刚添加的自增列的值

并且把获取到的主键值赋值给keyProperty="id"也就是user的id

<!--添加记录和获取主键值   92-->
  <insert id="insertReturnPrimaryKey">
    insert into u_user(phone, login_password,add_time)
    values(#{phone},#{loginPassword},#{addTime})

    <selectKey keyColumn="newId" keyProperty="id" resultType="int" order="AFTER">
      select LAST_INSERT_ID() as newId
    </selectKey>
  </insert>

4.2.3 实现类UserServiceImpl   91

//用户注册  91
    @Transactional(rollbackFor = Exception.class) //添加事务,发生异常就回滚  92
    @Override  //synchronized时同步方法的意思,考虑线程安全   92
    public synchronized int userRegister(String phone, String password) {

        int result = 0;//默认参数不正确  91
        if(CommonUtil.checkPhone(phone)
                &&(password!=null&&password.length()==32)){

            //判断手机号在库中是否存在   92
            User queryUser = userMapper.selectByPhone(phone);
            if(queryUser==null){//数据库中不存在此手机号,即用户没注册过,可以注册  92
                //注册密码MD5二次加密,给原始密码加盐  91
                String newPassword = DigestUtils.md5Hex( password + passwordSalt);

                //注册添加进u_user表
                User user = new User();
                user.setPhone(phone);
                user.setLoginPassword(newPassword);
                user.setAddTime(new Date());
                userMapper.insertReturnPrimaryKey(user);

                //解释,既然用户注册添加成功,我们就要给他开一个资金账户
                // 即添加一条记录到u_finance_account 92
                //获取主键user.getId()
                FinanceAccount account = new FinanceAccount();
                account.setUid(user.getId());
                account.setAvailableMoney(new BigDecimal("0"));
                financeAccountMapper.insertSelective(account);

                //成功result = 1
                result = 1;
            }else {
                //手机号存在
                result = 2;
            }

        }

        return result;
    }

4.3 检查验证码是否正确   90

4.3.1 业务接口

在micr-web

SmsService

//检查验证码  90
    boolean checkSmsCode(String phone,String code);

4.3.2 业务接口实现类   90

SmsCodeRegisterImpl

//检查验证码  90
    @Override
    public boolean checkSmsCode(String phone, String code) {
        //拼接key
        String key = RedisKey.KEY_SMS_CODE_REG+phone;
        if(stringRedisTemplate.hasKey(key)){//redis中右key
            //去除value
            String querySmsCode = stringRedisTemplate.boundValueOps(key).get();
            if(code.equals(querySmsCode)){//比较
                return true;
            }
        }
        
        return false;
    }

4.4 消费者 controller   90

micr-common

短信服务和注册功能_apache_14

micr-web

UserContorller   90-92

//用户注册  90
    @ApiOperation(value = "手机号注册用户")
    @PostMapping("/register")
    public RespResult userRegister(@RequestParam String phone,
                                   @RequestParam String pword,
                                   @RequestParam String scode){
        RespResult result = RespResult.fail();
        //1.检查参数
        if( CommonUtil.checkPhone(phone)){
            if(pword !=null && pword.length() == 32 ){
                //检查短信验证码
                if( smsService.checkSmsCode(phone,scode)){

                    //可以注册
                    int registerResult  = userService.userRegister(phone,pword);
                    if( registerResult == 1 ){//注册成功   92
                        result = RespResult.ok();
                    } else if( registerResult == 2 ){//手机号已注册过   92
                        result.setRCode(RCode.PHONE_EXISTS);
                    } else {//请求参数有误   92
                        result.setRCode(RCode.REQUEST_PARAM_ERR);
                    }

                } else {
                    //短信验证码无效
                    result.setRCode(RCode.SMS_CODE_INVALID);
                }
            } else {
                //请求参数有误
                result.setRCode(RCode.REQUEST_PARAM_ERR);
            }
        } else {
            //手机号格式不正确
            result.setRCode(RCode.PHONE_FORMAT_ERR);
        }
        return result;
    }

测试  92-93

使用postman   

首先,获取验证码

短信服务和注册功能_spring_15

短信服务和注册功能_apache_16

在测试注册,填好参数

我们可以使用md5的在线工具,生成一个密码帮助我们测试

短信服务和注册功能_json_17

短信服务和注册功能_spring_18

发送请求

短信服务和注册功能_json_19

看看数据库成功添加

短信服务和注册功能_apache_20

短信服务和注册功能_apache_21

如果我们用一样的手机号注册,会提示已经注册过了

短信服务和注册功能_apache_22

如果验证码失效了,还发送请求的话会提示验证码无效

短信服务和注册功能_json_23

举报

相关推荐

0 条评论