springboot秒杀课程学习整理1-3

1)实现手机验证码功能,用户注册功能,用户登入功能(这里讲开发流程,及本人遇到的问题,具体实现请看代码)

  1、拦截请求,获取请求参数(这里的consumes是个常量,可以定义在baseController里)

    @RequestMapping(value="/register",method={RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
                                     @RequestParam(name="telphone")String telphone,
                                     @RequestParam(name="otpCode")String otpCode,
                                     @RequestParam(name="name")String name,
                                     @RequestParam(name="gender")String gender,//性别
                                     @RequestParam(name="age")Integer age,
                                     @RequestParam(name="password")String password

2、使用传入的参数创建userModel对象,调用userService,将userModel转成userDO对象,使用userDOMapper插入数据库

      注意:此处有部分细节,需注意如使用userId查userPassword的那个表需要自定义,以及通过手机号查userInfo表也需要自定义,在最后一章我

      会把库的地址贴上

2)1、使用hibernate.validator对userModel进行校验

          【1】 创建存放校验信息的类ValidationResult

          【2】创建一个用于校验的类ValidateImpl,提供方法返回校验信息的方法,里面包括校验的具体实现

      2、密码使用md5加密存入数据库

 

下面是代码详情:

UserController

package com.miaoshaproject.controller;

import com.alibaba.druid.util.StringUtils;
import com.miaoshaproject.controller.viewobject.UserVO;


import com.miaoshaproject.error.BusinessException;
import com.miaoshaproject.error.EmBusinessError;
import com.miaoshaproject.response.CommonReturnType;
import com.miaoshaproject.service.impl.UserServiceImpl;
import com.miaoshaproject.service.model.UserModel;
import org.apache.tomcat.util.security.MD5Encoder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

@RestController
@RequestMapping("/user")
@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")//在跨域的情况下session是不支持共享的,前端也需要设置xhrFields:{widthCredentials:true}
public class UserController extends BaseController{
    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @RequestMapping("/getuser")
    @ResponseBody
    public CommonReturnType getUserById(@RequestParam(name="id")Integer id)throws BusinessException{
        UserVO userVO=new UserVO();
        UserModel userModel=userService.getUserById(id);
        if(userModel == null){
            throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
        }
        UserVO obj=converUserVOFromUserModel(userModel);
        return CommonReturnType.create(obj);
    }

    public UserVO converUserVOFromUserModel(UserModel userModel){
        UserVO userVO=new UserVO();
        BeanUtils.copyProperties(userModel,userVO);
        return userVO;
    }

    //用户获取opt短信验证码
    @RequestMapping(value="/getotp",method={RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType getOtp(@RequestParam(name="telphone")String telphone){
        //需要按照一定规则生成otp验证码
        Random random=new Random();
        int randomInt=random.nextInt(99999);
        randomInt += 10000;
        String otpCode=String.valueOf(randomInt);
        //将opt验证码同对应手机号关联,redis可用于分布式,
        // 这里使用httpsession的方式绑定手机号和code
        this.httpServletRequest.getSession().setAttribute(telphone,otpCode);

        //将opt验证码通过短信通道发送给用户,
        // 这里省略使用控制台的方式打印code码,在企业里开发这种做法是不允许的,
        // 这些是敏感信息
        System.out.println("telphone = " + telphone + "& otpCode = " + otpCode);
        return CommonReturnType.create(null);
    }
    //用户登入功能
    @RequestMapping(value="/login",method={RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType login(@RequestParam(name="telphone")String telphone,
                                  @RequestParam(name="password")String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        //入参校验
        if(StringUtils.isEmpty(telphone)||
        StringUtils.isEmpty(password)){
            throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR);
        }
        //验证登入是否合法
         UserModel userModel = userService.validateLogin(telphone,
                 this.EncodeByMd5(password));
        //添加登入成功的session
        this.httpServletRequest.getSession().setAttribute("IS_LOGIN",true);
        this.httpServletRequest.getSession().setAttribute("LOGIN_USER",userModel);

        return CommonReturnType.create(null);

    }

    //用户注册功能
    @RequestMapping(value="/register",method={RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType register(@RequestParam(name="telphone")String telphone,
                                     @RequestParam(name="otpCode")String otpCode,
                                     @RequestParam(name="name")String name,
                                     @RequestParam(name="gender")String gender,//性别
                                     @RequestParam(name="age")Integer age,
                                     @RequestParam(name="password")String password
                                     ) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        //验证手机号和对应的otpcode相符合
        String inSesstionOtpCode=(String)this.httpServletRequest.getSession().getAttribute(telphone);
        if(!com.alibaba.druid.util.StringUtils.equals(otpCode,inSesstionOtpCode)){
            throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"短信验证码错误");
        }

        //用户的注册流程
        UserModel userModel=new UserModel();
        userModel.setName(name);
        userModel.setGender(gender);
        userModel.setAge(age);
        userModel.setTelphone(telphone);
        userModel.setRegisterMode("byphone");
        userModel.setEnCrptPassword(this.EncodeByMd5(password));

        userService.register(userModel);

        return CommonReturnType.create(null);
    }
    //md5的加密计算
    //java自带的md5只支持16位
    public String EncodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        //确定计算方法
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64en= new BASE64Encoder();
        String newStr =base64en.encode(md5.digest(str.getBytes("utf-8")));
        return newStr;
    }
}
View Code

UserServiceIpml

package com.miaoshaproject.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.miaoshaproject.dao.UserDOMapper;
import com.miaoshaproject.dao.UserPasswordDOMapper;
import com.miaoshaproject.dataobject.UserDO;
import com.miaoshaproject.dataobject.UserPasswordDO;
import com.miaoshaproject.error.BusinessException;
import com.miaoshaproject.error.EmBusinessError;
import com.miaoshaproject.service.UserService;
import com.miaoshaproject.service.model.UserModel;
import com.miaoshaproject.validator.ValidationResult;

import com.miaoshaproject.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDOMapper userDOMapper;
    @Autowired
    private UserPasswordDOMapper userPasswordDOMapper;
    @Autowired
    private ValidatorImpl validator;

    @Override
    public UserModel getUserById(int id) {
        UserDO userDO=userDOMapper.selectByPrimaryKey(id);
        UserPasswordDO userPasswordDO=userPasswordDOMapper.selectByUserId(id);
        return converFromUserDO(userDO,userPasswordDO);
    }

    public UserModel converFromUserDO (UserDO userDO,UserPasswordDO userPasswordDO){
        UserModel userModel=new UserModel();
        if(userDO==null){
            return null;
        }
        BeanUtils.copyProperties(userDO,userModel);
        if(userPasswordDO != null){
            userModel.setEnCrptPassword(userPasswordDO.getEncrptPassword());
        }
        return userModel;
    }

    @Override
    @Transactional
    public void register(UserModel userModel) throws BusinessException {
        //这里需要严谨一些,对所有字段判断不为空
        if(userModel == null){
            throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR);
        }
        ValidationResult result=validator.validate(userModel);
        if(result.isHasError()){
            throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,result.getErrMsg());
        }

        //这里需要注意的点是在数据库里设置索引手机号是唯一的
        try{
            UserDO userDO=convertFromModel(userModel);
            userDOMapper.insertSelective(userDO);
        }catch(DuplicateKeyException ex){
            throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"手机号已重复注册");
        }
        UserDO newUserDO=userDOMapper.selectByTelphone(userModel.getTelphone());
        userModel.setId(newUserDO.getId());
        UserPasswordDO userPasswordDO=convertPasswordFormUserModel(userModel);
        userPasswordDOMapper.insertSelective(userPasswordDO);
        return;
    }
    private UserPasswordDO convertPasswordFormUserModel(UserModel userModel){
       if(userModel==null){
           return null;
       }
       UserPasswordDO userPasswordDO=new UserPasswordDO();
       userPasswordDO.setEncrptPassword(userModel.getEnCrptPassword());

       userPasswordDO.setUserId(userModel.getId());
       return userPasswordDO;
    }
    private UserDO convertFromModel(UserModel userModel){
        if(userModel == null){
            return null;
        }
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userModel,userDO);
        return userDO;
    }

    //登入是否合法

    @Override
    public UserModel validateLogin(String telphone, String password) throws BusinessException {
        //通过手机获取用户信息,新增查询方式通过手机来获取用户信息
         UserDO userDO=userDOMapper.selectByTelphone(telphone);
         if(userDO==null){
             throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"用户不存在");
         }
         UserPasswordDO userPasswordDO=userPasswordDOMapper.selectByUserId( userDO.getId());

        //比对用户信息内加密的密码是否和传输进来的一致
        if(!StringUtils.equals(userPasswordDO.getEncrptPassword(),password)){
            throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"账号或密码不存在");
        }
        UserModel userModel=converFromUserDO(userDO,userPasswordDO);
        return userModel;
    }
}
View Code

ValidationResult

package com.miaoshaproject.validator;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;

@Component
public class ValidatorImpl implements InitializingBean {
    //javax.validator
    private Validator validator;

    @Override
    public void afterPropertiesSet() throws Exception {
     //将hibernate validator通过工厂的初始化方式使其实例化
        this.validator = Validation.buildDefaultValidatorFactory().getValidator();

    }

    //事项校验方法返回校验结果
    public ValidationResult validate(Object bean){
        ValidationResult result=new ValidationResult();
        Set<ConstraintViolation<Object>> constraintViolationsSet=validator.validate(bean);
        if(constraintViolationsSet.size()>0){
            //有错误
            result.setHasError(true);
            /*这里有报错说不支持7及以下的语言等级,
            * file->project strcture->module->选择resource上面的language level给为7以上的
            * file->setting->compiler->java Compiler->将version改为7以上
            * */
            constraintViolationsSet.forEach(constraintViolation->{
                String errMsg=constraintViolation.getMessage();
                String propertyName=constraintViolation.getPropertyPath().toString();
                result.getErrMsgMap().put(propertyName,errMsg);
            });
        }
        return result;
    }
}
View Code

ValidateImpl

package com.miaoshaproject.validator;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;

@Component
public class ValidatorImpl implements InitializingBean {
    //javax.validator
    private Validator validator;

    @Override
    public void afterPropertiesSet() throws Exception {
     //将hibernate validator通过工厂的初始化方式使其实例化
        this.validator = Validation.buildDefaultValidatorFactory().getValidator();

    }

    //事项校验方法返回校验结果
    public ValidationResult validate(Object bean){
        ValidationResult result=new ValidationResult();
        Set<ConstraintViolation<Object>> constraintViolationsSet=validator.validate(bean);
        if(constraintViolationsSet.size()>0){
            //有错误
            result.setHasError(true);
            /*这里有报错说不支持7及以下的语言等级,
            * file->project strcture->module->选择resource上面的language level给为7以上的
            * file->setting->compiler->java Compiler->将version改为7以上
            * */
            constraintViolationsSet.forEach(constraintViolation->{
                String errMsg=constraintViolation.getMessage();
                String propertyName=constraintViolation.getPropertyPath().toString();
                result.getErrMsgMap().put(propertyName,errMsg);
            });
        }
        return result;
    }
}
View Code

 

 

     

      

posted @ 2019-04-20 17:38  LLC-Mite  阅读(168)  评论(0编辑  收藏  举报