记录一次完成的注册过程

点击【立即注册】按钮发送

http://localhost:20000/regist 请求

在这里插入图片描述
注册成功后重定向到登录界面:

@Controller
public class registerController {
    @PostMapping("/regist")
    public String regist(){
        

        return "redirect:/login.html";
    }
}

新建一个VO来接收前端表单传过来的数据并使用JSR303来校验:

@Data
public class UserRegisterVo {
   @NotEmpty(message = "用户名必须提交")
   @Length(min = 6,max = 18,message = "用户名必须是6-18位字符")
   private String userName;
   @NotEmpty(message = "密码不能为空")
   @Length(min = 6,max = 18,message = "密码必须是6-18位字符")
   private  String passWord;
   @Pattern(regexp = "^[1]([3-9])[0-9]{9}$",message = "手机号格式不正确")
   private String phone;
   @NotEmpty(message = "验证码必须填写")
   @Length(min = 6,max = 6,message = "验证码只能是6位")
   private String code;
}

在将前端的input框加上name属性和后端vo进行对应以保证后端能成功接收到前端传过来的数据:

<input name="userName" maxlength="20" type="text" placeholder="您的用户名和登录名" >
<input name="passWord" maxlength="20" type="password" placeholder="建议至少使用两种字符组合">
<input class="phone" name="phone" id="phoneNumber" maxlength="20" type="text" placeholder="建议使用常用手机">
<input  name="code" maxlength="20" type="text" placeholder="请输入验证码" class="caa">

表单后端校验逻辑
准备好之后开始写表单后端校验逻辑
标注@Valid处理校验,使用BindingResult来收集校验信息RedirectAttributes给页面返回数据。

校验的主要逻辑是:如果JSR303校验失败,就使用BindingResult来收集错误信息成一个map集合,并将错误信息通过RedirectAttributes(或者Model)返回给前端,在重新重定向到注册页

    @PostMapping("/regist")
    public String regist(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){
        /**
         * 表单后端校验逻辑
         */
         if(result.hasErrors()){
             //将校验错误信息返回给页面,收集成一个map
             Map<String, String> errors = result.getFieldErrors().stream()
                     .collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage));
             redirectAttributes.addFlashAttribute("errors",errors);
             //校验出错重定向返回到注 册页
             return "redirect:/register";
         }

短信验证码校验逻辑:

主要逻辑:通过刚才写的vo收集前端表单传过来的数据能拿到所发送的短信验证码,在之前写发送短信验证码功能的时候已经将验证码放到了redis里了(参考jdmall-auth-service里的loginController)因此,我们只需要将redis里的验证码拿出来并与前端传过来的验证码作比较就可以了。

如果redis里边没有验证码,那肯定是超过了redis里存放的时间,因为一但点击发送验证码按钮必然会将验证码存到redis中。

完整表单验证以及短信验证码校验逻辑代码:

@Controller
public class registerController {
    @Autowired
    RedisTemplate redisTemplate;
    @PostMapping("/regist")
    public String regist(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){
        /**
         * 表单校验逻辑
         */
         if(result.hasErrors()){
             //将校验错误信息返回给页面,收集成一个map
             Map<String, String> errors = result.getFieldErrors().stream()
                     .collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage));
             redirectAttributes.addFlashAttribute("errors",errors);
             //校验出错重定向返回到注 册页
             return "redirect:/register";
         }
        /**
         * 短信验证码校验逻辑以及开始注册
         */
        //1、获取表单验证码
        String code=vo.getCode();
        //2、在Redis里取出验证码
        String s = (String)redisTemplate.opsForValue().get(authConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
       //判断redis里是否有验证码有的话进行第3步,没有直接进入 redis里的验证码过期后的逻辑
        if(!StringUtils.isEmpty(s)){
           //3、将vo收集的验证码与redis的验证码作比对
         if(code.equals(s.split("_")[0])){
             //校验验证码成功后,删除验证码
             redisTemplate.delete(authConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
             //验证码通过,开始真正的注册,远程调用
             开始真正的注册功能:远程调用完整代码整合在下边 

         }else{
             //验证码对比错误,校验失败
             Map<String,String> errors=new HashMap<>();
             errors.put(code,"验证码错误");
             redirectAttributes.addFlashAttribute("errors",errors);
             return "redirect:/register";
         }
       }else{
            //redis里的验证码过期后的逻辑
            Map<String,String> errors=new HashMap<>();
            errors.put(code,"验证码已过期");
            redirectAttributes.addFlashAttribute("errors",errors);
            return "redirect:/register";
       }
        return "redirect:/login.html";
    }
}

都校验完毕之后就开始真正的注册了,注册逻辑写在另一个服务上,最后进行远程调用:
在jdmall-member中的MemberController中写一个映射

  @PostMapping("/registMember")
    public R register(@RequestBody MemberRegistVo registVo){
       try {
           memberService.regist(registVo);
       }catch (Exception e){
           
        return R.error(15001,"手机号或者用户名已存在");
       }

     return R.ok();
    }

MemberRegistVo 里边收集的是表单传过来的信息和UserRegisterVo一样

注册功能就是将传过来的数据保存到数据库里,就是注意一些细节就行了,直接上代码再解释。

 @Override
    public void regist(MemberRegistVo registVo) {
        MemberEntity memberEntity = new MemberEntity();
        //设置默认等级
        MemberLevelEntity memberLevelEntity=memberLevelDao.getDefaultLevel();
        memberEntity.setLevelId(memberLevelEntity.getId());
        //设置其它信息
        //检查用户名和手机号是否唯一,为了让controller能感知异常,异常机制
        checkPhoneIsWeiYi(registVo.getPhone());
        checkUserNameIsWeiYi(registVo.getUserName());
        memberEntity.setUsername(registVo.getUserName());
        memberEntity.setMobile(registVo.getPhone());
        //保存密码并加密:md5盐值加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encoderCode=bCryptPasswordEncoder.encode(registVo.getPassWord());
        memberEntity.setPassword(encoderCode);
        this.save(memberEntity);


    }

    @Override
    //检查手机号是否唯一
    public void checkPhoneIsWeiYi(String phone) {
        int mobile = this.count(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if(mobile>0){
        //如果存在就刨除异常
            throw new RRException("手机号已存在");
        }



    }

    @Override
    //检查用户名是否唯一
    public void checkUserNameIsWeiYi(String userName) {
        int CountUserName = this.count(new QueryWrapper<MemberEntity>().eq("username", userName));

        if(CountUserName>0){
        //如果存在就抛出异常
            throw new RRException("用户名已存在");
        }

    }

将对应数据插入到数据库并设置其默认信息,注意密码要是用MD5盐值加密,用户名和手机号要有唯一性因此需要检查手机号是否唯一,checkPhoneIsWeiYi()、checkUserNameIsWeiYi()这两个方法实现了。

最终再使用openFeign进行远程调用:
在这里插入图片描述

完整注册逻辑代码:

@Controller
public class registerController {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    memberFeignService memberFeignService;
    @PostMapping("/regist")
    public String regist(@Valid UserRegisterVo vo, BindingResult result, RedirectAttributes redirectAttributes){
        /**
         * 表单校验逻辑
         */
         if(result.hasErrors()){
             //将校验错误信息返回给页面,收集成一个map
             Map<String, String> errors = result.getFieldErrors().stream()
                     .collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage));
             redirectAttributes.addFlashAttribute("errors",errors);
             //校验出错重定向返回到注 册页
             return "redirect:/register";
         }
        /**
         * 短信验证码校验逻辑以及开始注册
         */
        //1、获取表单验证码
        String code=vo.getCode();
        //2、在Redis里取出验证码
        String s = (String)redisTemplate.opsForValue().get(authConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
       //判断redis里是否有验证码有的话进行第3步,没有直接进入 redis里的验证码过期后的逻辑
        if(!StringUtils.isEmpty(s)){
           //3、将vo收集的验证码与redis的验证码作比对
         if(code.equals(s.split("_")[0])){
             //校验验证码成功后,删除验证码
             redisTemplate.delete(authConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
             //验证码通过,开始真正的注册,远程调用
             R r = memberFeignService.register(vo);
             if(r.getCode()==0){
                 //远程注册成功
                 return "redirect:/login.html";
             }else{
                 //远程注册失败
                 Map<String,String> errors=new HashMap<>();
                 errors.put("msg",r.getData(new TypeReference<String>(){}));
                 redirectAttributes.addFlashAttribute("errors",errors);
                 return  "redirect:/register";
             }


         }else{
             //验证码对比错误,校验失败
             Map<String,String> errors=new HashMap<>();
             errors.put(code,"验证码错误");
             redirectAttributes.addFlashAttribute("errors",errors);
             return "redirect:/register";
         }
       }else{
            //redis里的验证码过期后的逻辑
            Map<String,String> errors=new HashMap<>();
            errors.put(code,"验证码已过期");
            redirectAttributes.addFlashAttribute("errors",errors);
            return "redirect:/register";
       }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值