论坛项目之用户部分

注册接口

实现思路

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("用户密码修改成功!" );}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/42353.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是P2P?

P2P (Peer-to-Peer) 是一种分布式的网络架构&#xff0c;其中各个节点&#xff08;通常被称为“peers”或“节点”&#xff09;直接进行数据共享和交换&#xff0c;而无需依赖中央服务器。P2P 网络强调平等的参与和共享&#xff0c;每个节点既可以是数据的消费者&#xff08;下…

推进深度融合 打造智慧媒体

以下内容来自于易知微官网&#xff0c;点击一下&#xff0c;即可进入官网了解详情。 注意&#xff1a;案例数据均为虚拟数据 数字改革是一场波及经济社会发展全局、涵盖生产力到生产关系的全方位变革。在数字化时代&#xff0c;以数字改革赋能媒体深度融合已然成为时代所向、…

每日一题——连续子数组的最大和

题目 输入一个长度为n的整型数组array&#xff0c;数组中的一个或连续多个整数组成一个子数组&#xff0c;子数组最小长度为1。求所有子数组的和的最大值。 数据范围:1<n<2105 −100<a[i]<100 要求:时间复杂度为 O(n)&#xff0c;空间复杂度为 O(n) 示例1 输入…

ubuntu中安装python

最简单方便的是 apt 使用第三方的 ppa 源&#xff0c;然后直接 apt 安装 python3.9 安装 software-properties-common 获取add-apt-repository命令&#xff1a;apt install -y software-properties-common添加第三方的 ppa 源&#xff1a;add-apt-repository ppa:deadsnakes/p…

Spring系列篇--关于Spring Bean完整的生命周期【附有流程图,超级易懂】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Spring Bean是单例模式还是多例模式 二…

Kafka如何保证消息⼀定能被消费

Kafka 通过多种机制来保证消息一定能被消费&#xff0c;从而实现数据的可靠性和持久性。 以下是一些常见的方法和策略来提高消息的可靠性&#xff1a; 复制机制&#xff1a; Kafka 使用了分区和副本的概念。每个分区可以有多个副本&#xff0c;分布在不同的 Broker 上。当消息…

k8s 自身原理 3

前面有分享到 master 主节点上的 四个组件&#xff0c;etcd&#xff0c;ApiServer&#xff0c;scheduler&#xff0c;controller manager 接下来我们分享一波 woker 节点上的组件&#xff0c;xdm 还记得 worker 节点上都有什么吗&#xff1f; kubeletkube-proxy实际的服务对应…

【数据结构】栈和队列常见题目

文章目录 有效的括号用队列实现栈两个队列实现栈一个队列实现栈用栈实现队列设计循环队列最小栈栈的压入&弹出序列逆波兰表达式队列:先进先出 栈:后进先出 有效的括号 https://leetcode.cn/problems/valid-parentheses/ class Solution {public:bool isValid(string s) {…

如何让多线程步调一致?

前几天老板突然匆匆忙忙的过来说对账系统最近越来越慢了&#xff0c;能不能快速优化一下&#xff1f;我了解了对账系统的业务后&#xff0c;发现还是挺简单的&#xff0c;用户通过在线商城下单&#xff0c;会生成电子订单&#xff0c;保存在订单库。之后物流会生成派送单给用户…

Redis - 数据类型映射底层结构

简介 从数据类型上体现就是&#xff0c;同一个数据类型&#xff0c;在不同的情况下会使用不同的编码类型&#xff0c;底层所使用的的数据结构也不相同。 字符串对象 字符串对象的编码可以是 int、raw 和 embstr 三者之一。 embstr 编码是专门用于保存简短字符串的一种优化编…

每日一学——无线基础知识

无线局域网&#xff08;Wireless Local Area Network&#xff0c;简称 WLAN&#xff09;是一种使用无线通信技术连接多个无线终端设备的局域网。它通常基于无线电波传输数据&#xff0c;并使用无线接入点&#xff08;Access Point&#xff0c;简称 AP&#xff09;来连接无线设备…

网络安全--负载均衡

负载均衡 webshell实践 一、负载均衡配置 1.在全局的http下写下它&#xff1a; upstream nginx_boot{# 30s内检查心跳发送两次包&#xff0c;未回复就代表该机器宕机&#xff0c;请求分发权重比为1:2server 192.168.0.000:8080 weight100 max_fails2 fail_timeout30s; ser…

LeetCode150道面试经典题-- 合并两个有序链表(简单)

1.题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 2.示例 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输…

k8s 中快速启动curl pod 做api test

场景 k8s上运行的pod需要进行api测试,由于开发使用的镜像都是最小化构建,不能保证现有的pod中一定有curl工具,于是需要启动一个带有curl工具的测试pod专门进行api测试 指令 kubectl run curl-test-pod --imagecurlimages/curl -n {namespace} -i --tty -- sh上述指令实现在指…

“一日之际在于晨”,欢迎莅临WAVE SUMMIT上午场:Arm 虚拟硬件早餐交流会

8月16日&#xff0c;盛夏的北京将迎来第九届WAVE SUMMIT深度学习开发者大会。在峰会主论坛正式开启前&#xff0c;让我们先用一份精美的元气早餐&#xff0c;和一场“Arm虚拟硬件交流会”&#xff0c;唤醒各位开发小伙伴的开发魂&#xff01; 8月16日&#xff0c;WAVE SUMMIT大…

时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计学习总结参考资料 预测效果 基本介绍 时序预测 | MATLAB实现WOA-…

华为OD真题--字符串中最小的整数和--带答案

1. 华为OD机考题 答案 2023华为OD统一考试&#xff08;AB卷&#xff09;题库清单-带答案&#xff08;持续更新&#xff09; 2023年华为OD真题机考题库大全-带答案&#xff08;持续更新&#xff09; 2. 面试题 一手真实java面试题&#xff1a;2023年各大公司java面试真题汇总--…

java导入excel图片处理

直接看代码吧&#xff0c;主要逻辑吧excel的图片拿到 压缩上传获取url // 将文件转成XSSFWorkbook工作簿XSSFWorkbook wb new XSSFWorkbook(uploadFile);// 获取工作薄中第一个excel表格XSSFSheet sheet wb.getSheetAt(0);// 核心&#xff1a;&#xff1a;&#xff1a;获取ex…

R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

《论文阅读14》FAST-LIO

一、论文 研究领域&#xff1a;激光雷达惯性测距框架论文&#xff1a;FAST-LIO: A Fast, Robust LiDAR-inertial Odometry Package by Tightly-Coupled Iterated Kalman Filter IEEE Robotics and Automation Letters, 2021 香港大学火星实验室 论文链接论文github 二、论文概…