springboot秒殺課程學習整理1-3
阿新 • • 發佈:2019-04-20
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