1. 程式人生 > >springboot秒殺課程學習整理1-3

springboot秒殺課程學習整理1-3

beanutils ping 不存在 hone param for rim mpi cli

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

springboot秒殺課程學習整理1-3