注冊接口
實現思路
1.特殊字段檢查(比如性別沒有給出需要給出默認值)
2.對比檢查兩次輸入的密碼是否一致,不一致報錯
3.利用UUID生成隨機‘鹽’值,并使用密碼進行MD5加密后與‘鹽’進行拼接,生成加密后的密碼
4.創建User對象并在數據庫中查詢該User對象是否存在,存在則報錯
5.補充User對象的其他信息(文章數量、用戶狀態、用戶刪除狀態、注冊時間等)
6.使用insert方法將用戶寫入數據庫,返回方法執行結果
實例代碼
Contorller
@PostMapping("/register")
@ApiOperation("注冊新用戶(普通)的方法")public AppResult register(@RequestParam("username")@NonNull @ApiParam(value = "用戶名") String username, @RequestParam("nickname")@NonNull @ApiParam(value = "昵稱") String nickname, @RequestParam(value = "gender",required = false)@ApiParam(value = "性別") Byte gender , @RequestParam("password")@NonNull @ApiParam(value = "密碼") String password, @RequestParam("passwordRepeat") @NonNull @ApiParam(value = "確認密碼") String passwordRepeat){//測試數據的有效性if(gender==null||gender<0||gender>2){//如果錯誤,我們將性別信息進行清空gender=2;}//判斷密碼和確認密碼是否相同if(!password.equals(passwordRepeat)){log.error(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));}//對密碼進行加密String salt = UUIDUtils.UUID_32();String newPassword = MD5Utils.md5Salt(password, salt);//將所有字段信息儲存User user = new User();user.setUsername(username);user.setNickname(nickname);user.setGender(gender);user.setPassword(newPassword);user.setSalt(salt);userService.createCommonUser(user);return AppResult.success("用戶新增成功!");}
Service
public void createCommonUser(User user) {//空指針排除if(user==null){//日志記錄錯誤信息log.error("輸入的用戶信息不存在");throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));}//從數據庫中查詢是否存在該數據User checkUser = userMapper.selectByUsername(user.getUsername());//存在拋出并記錄日志/if(checkUser !=null){//記錄日志log.error(ResultCode.FAILED_USER_EXISTS.toString()+"name="+checkUser.getUsername());//拋出異常throw new ApplicationException(AppResult.failed(ResultCode. FAILED_USER_EXISTS));}//不存在則填充并插入數據,之后返回結果//補充結果if(user.getGender()==null) {//設置默認的性別user.setGender((byte) 2);}//設置其他值//設置發帖數量user.setPhoneNum("");user.setArticleCount(0);//設置是否為管理員user.setIsAdmin((byte) 0);//設置狀態user.setState((byte) 0);//設置是否刪除user.setDeleteState((byte) 0);//設置創建時間Date date = new Date();user.setCreateTime(date);user.setUpdateTime(date);//查看返回結果int result = userMapper.insertSelective(user);log.info("result="+result);if(result!=1){//記錄錯誤日志log.error(ResultCode.FAILED_CREATE.toString());//拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));}//最終記錄成功日志log.info("注冊用戶成功:"+user.getUsername());}
登錄接口
實現思路
1.使用@NonNull注解確保賬號密碼不為空
2.從數據庫中查詢是否存在該數據,如果不存在直接報錯
3.從數據庫中取出對應數據的‘鹽’值,使用輸入用戶對應的密碼進行MD5加密后使用該‘鹽’進行拼接,之后與數據庫中的密碼進行比對是否相等,不相等直接報錯
4.登錄成功后建立對應的session,并設置session對應的屬性作為我們后續檢查是否登錄的依據(session.setAttribute(AppConfig.USER_SESSION, loginUser)
實例代碼
Controller
@ApiOperation("登錄方法")@PostMapping("/login")public AppResult login(HttpServletRequest request, @ApiParam(value = "用戶名") @RequestParam(value = "username")@NonNull String username, @ApiParam(value = "密碼")@RequestParam(value = "password")@NonNull String password){//調用service登錄方法User loginUser = userService.login(username, password);//存儲sessionHttpSession session=request.getSession(true);session.setAttribute(AppConfig.USER_SESSION, loginUser);//返回結果return AppResult.success("登錄成功",loginUser);}
Service
@Overridepublic User login(String username, String password) {//判斷賬號密碼是否為空if(StringUtils.isEmpty(username)&&StringUtils.isEmpty(password)){//打印錯誤的日志信息log.error(ResultCode.ERROR_IS_NULL.toString());//拋出異常throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));}//從數據庫中查詢數據User user = selectByUsername(username);if(user==null){//記錄日志并拋出異常//數據庫中沒有該用戶記錄則直接報錯//為了提高數據庫的安全性,即使用戶不存在,我們也返回賬號或密碼錯誤log.error(ResultCode.FAILED_LOGIN.toString());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));}//查詢到比對密碼String truePassword=user.getPassword();//對密碼進行md5加密String repeatPassword= MD5Utils.md5Salt(password, user.getSalt());if(!repeatPassword.equals(truePassword)){//記錄錯誤日志log.error(ResultCode.FAILED_LOGIN.toString());//密碼錯誤返回報錯信息throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));}//密碼相同登陸成功,返回用戶信息log.info("用戶登錄成功!");return user;}
退出登錄接口
實現思路
1.通過HttpServletRequest獲取session對象
2.將session對象中將我們此前設置的屬性值去除
3.將我們設置的session對象設置無效化(invalidate),并進行頁面跳轉
實例代碼
controller
@ApiOperation("用戶退出方法")@GetMapping("/logout")public AppResult logout(HttpServletRequest request){//檢查session是否有效HttpSession session = request.getSession(false);if(session==null){//記錄錯誤日志log.error(ResultCode.USER_NOT_LOG.toString());//返回錯誤信息throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));}//去除sessionObject user = session.getAttribute(AppConfig.USER_SESSION);log.info("用戶退出"+user);session.invalidate();//返回結果return AppResult.success("用戶退出成功.");}
查看用戶信息接口
實現思路
1.根據前端傳來的參數中是否包括id來判斷當前需要顯示的信息是對應文章的作者信息還是當前登錄的用戶信息
2.如果是當前登錄的用戶,直接在session中根據鍵獲取對應的值(當前登錄的用戶),將這個信息直接返回給前端即可
3.如果是對應文章的用戶,我們需要根據主鍵從數據庫中查詢信息并將該信息返回
實例代碼
controller
@GetMapping("/info")@ApiOperation("展示用戶信息的方法")public AppResult userInfo(HttpServletRequest request ,@ApiParam(value = "用戶id")@RequestParam(value = "id" ,required = false) Long id){//判斷是否存在id//不存在id返回當前登錄的用戶信息if(id==null){//獲取sessionHttpSession session = request.getSession(false);//session為null說明用戶未登錄if(session==null){//記錄錯誤日志log.error(ResultCode.USER_NOT_LOG.toString());//返回錯誤信息throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));}User user = (User)session.getAttribute(AppConfig.USER_SESSION);if(user==null){//記錄錯誤日志log.error(ResultCode.USER_NOT_LOG.toString());//返回錯誤信息throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));}return AppResult.success("用戶查詢成功!",user);}//存在id返回指定id的用戶else{User user = userService.selectByPrimaryKey(id);if(user==null){log.error(ResultCode.FAILED_USER_NOT_EXISTS.toString());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));}return AppResult.success("用戶查詢成功",user);}}
service
@Overridepublic User selectByPrimaryKey(Long id) {//判斷id是否為空if(id==null){log.error(ResultCode.ERROR_IS_NULL.toString());throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));}//調用方法return userMapper.selectByPrimaryKey(id);}
修改用戶信息接口
實現思路
1.通過當前session獲取當前登錄的用戶與需要修改信息的用戶id進行比對判斷是否有權進行信息的修改
2.有權進行休息的修改則調用service進行信息的修改,其中在service中對需要修改的字段進行設置,最后調用mapper對應的selective方法進行數據處理
實例代碼
controller
@ApiOperation("修改用戶個人信息的方法!")@PostMapping("/modify")public AppResult modifyInfo (HttpServletRequest request,@ApiParam("用戶Id") @RequestParam("id") @NonNull Long id,@ApiParam("性別") @RequestParam(value = "gender", required = false) Byte gender,@ApiParam("昵稱") @RequestParam(value = "nickname", required = false) String nickname,@ApiParam("電話號碼") @RequestParam(value = "phoneNum", required = false) String phoneNum,@ApiParam("郵箱") @RequestParam(value = "email", required = false) String email,@ApiParam("個人簡介") @RequestParam(value = "remark", required = false) String remark) {// 校驗if (gender == null&& StringUtils.isEmpty(nickname)&& StringUtils.isEmpty(phoneNum)&& StringUtils.isEmpty(email)&& StringUtils.isEmpty(remark)) {// 參數同時為空時返回錯誤信息return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE.toString());}// 校驗傳入的Id是否為當前登錄用戶HttpSession session = request.getSession();User user = (User) session.getAttribute(AppConfig.USER_SESSION);if (user.getId() != id) {// 返回錯誤return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED.toString());}// 調用serviceuserService.modifyInfo(id, gender, nickname, phoneNum, email, remark);// 重新獲取用戶信息,更新sessionuser = userService.selectByPrimaryKey(id);session.setAttribute(AppConfig.USER_SESSION, user);// 返回結果return AppResult.success();
service
@Overridepublic void modifyInfo(Long id, Byte gender, String nickname, String phoneNum, String email, String remark) {// 非空校驗,id為null 或 其他的參數全部為nullif (id == null || (gender == null&& StringUtils.isEmpty(nickname)&& StringUtils.isEmpty(phoneNum)&& StringUtils.isEmpty(email)&& StringUtils.isEmpty(remark))) {log.warn(ResultCode.ERROR_IS_NULL.toString());throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));}// 校驗用戶狀態User user = userMapper.selectByPrimaryKey(id);if (user == null || user.getDeleteState() == 1) {log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));}// 構造一個修改對象User updateUser = new User();// 設置IdupdateUser.setId(id);// 設置昵稱if (!StringUtils.isEmpty(nickname)) {updateUser.setNickname(nickname);}// 設置電話if (!StringUtils.isEmpty(phoneNum)) {updateUser.setPhoneNum(phoneNum);}// 設置郵箱if (!StringUtils.isEmpty(email)) {updateUser.setEmail(email);}// 個人簡介if (!StringUtils.isEmpty(remark)) {updateUser.setRemark(remark);}// 性別if (gender != null && gender >= 0 && gender <= 2) {updateUser.setGender(gender);}// 調用DAOint row = userMapper.updateByPrimaryKeySelective(updateUser);if (row != 1) {log.warn(ResultCode.ERROR_UPDATE.toString());throw new ApplicationException(AppResult.failed(ResultCode.ERROR_UPDATE));}}
修改密碼接口
實現思路
1.通過session獲得當前登錄的用戶,并判斷是否有權修改對應id用戶的密碼(id是否相等)
2.判斷輸入的新密碼和重復密碼是否相等
3.進入service通過id從數據庫中查看并判斷當前用戶是否存在
4.獲取對應用戶的salt并使用md5對輸入的原密碼加密并與之拼接后再與數據庫中的原密碼進行比對,判斷輸入的原密碼是否正確
5.上述比對全部通過之后生成新的salt,將密碼加密后進行存儲
實例代碼
controller
@ApiOperation("修改密碼的方法")
@PostMapping("/modifyPwd")public AppResult modifyPassword(HttpServletRequest request,@NonNull@RequestParam(value = "id")@ApiParam(value = "用戶id") Long id,@NonNull@RequestParam("oldPassword")@ApiParam(value = "用戶的舊密碼") String oldPassword,@NonNull@RequestParam("newPassword")@ApiParam(value = "新密碼") String newPassword,@NonNull @RequestParam("passwordRepeat")@ApiParam(value = "重復密碼") String passwordRepeat){//判斷當前用戶是否登錄,沒有登錄直接報錯HttpSession session = request.getSession(false);if(session==null){log.error(ResultCode.USER_NOT_LOG.toString());throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));}User loginUser =(User) session.getAttribute(AppConfig.USER_SESSION);if(loginUser==null){log.error(ResultCode.USER_NOT_LOG.toString());throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));}//登錄之后判斷當前用戶是否有權修改密碼//無權直接報錯if(loginUser.getId()!=id){log.error(ResultCode.FAILED_UNAUTHORIZED.toString());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UNAUTHORIZED));}//判斷兩次密碼是否一致if(!newPassword.equals(passwordRepeat)){//密碼不一致進行報錯log.error(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));}//密碼一致則進行修改信息userService.modifyPassword(id, oldPassword, newPassword, passwordRepeat);log.info("密碼修改成功,"+loginUser.getUsername());return AppResult.success("密碼修改成功");}
service
public void modifyPassword(Long id, String oldPassword, String newPassword, String passwordRepeat) {//判斷id對應的用戶是否存在User checkUser = userMapper.selectByPrimaryKey(id);//用戶不存在直接報錯if(checkUser==null){//記錄錯誤信息log.error(ResultCode.FAILED_USER_NOT_EXISTS.toString());//進行報錯throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));}//如果用戶存在更新信息//判斷原密碼和輸入的原密碼是否相同,不相同直接報錯//對輸入的密碼進行加密String oldSalt = checkUser.getSalt();String realOldPassword = MD5Utils.md5Salt(oldPassword, oldSalt);if(!realOldPassword.equals(checkUser.getPassword())){log.error(ResultCode.FAILED_PASSWORD.toString());//報錯throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PASSWORD));}//如果相同繼續修改//創建對象并修改User user = new User();//生成加密字符String salt = UUIDUtils.UUID_32();//進行密碼加密String realPassword = MD5Utils.md5Salt(newPassword, salt);//將salt存入user.setSalt(salt);user.setPassword(realPassword);user.setId(id);//修改個人信息int result = userMapper.updateByPrimaryKeySelective(user);if(result!=1){log.error(ResultCode.ERROR_UPDATE.toString());AppResult.failed(ResultCode.ERROR_UPDATE);}//生成修改成功的日志log.info("用戶密碼修改成功!" );}