后端系统开发之——功能完善

原文地址:https://blog.yiming1234.cn/?p=830

下面是正文内容:

前言

通过SpringBoot开发用户模块的部分也就差不多要结束了,这一片文章就主要提一些在系统开发中需要注意到的细节部分和功能,也就是剩余的部分。

但是这个专栏只介绍了系统后端用户模块的开发,因为用户模块在大部分java后端的开发上都是通用必须掌握的。

而系统需要实现的具体功能比如说文章的发表,出入库的登记查询等等,则需要另起专栏去进行描述。

正文

获取更新用户信息/更新用户密码

由于这一部分接口的开发,和前面提到的注册登录接口的开发步骤大同小异,所以就合并之后简单描述一下了。

Controller层(UserController.java)

@GetMapping("/userinfo")public Result<User> userinfo(/*@RequestHeader(name = "Authorization") String token*/){//根据用户名查询用户/*Map<String, Object> map = JwtUtil.parseToken(token);String username = (String) map.get("username");*/Map<String, Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User user = userService.findByUserName(username);return Result.success(user);}@PtachMapping("/update")public Result<User> update(@RequestBody User user){userService.update(user);return Result.success();}@PatchMapping("/updateAvatar")public Result updateAvater(@RequestParam @URL String avatarUrl){userService.updateAvatar(avatarUrl);return Result.success();}

Service层(UserServiceImpl.java)

    @Overridepublic void update(User user){user.setUpdateTime(LocalDateTime.now());userMapper.update(user);}@Overridepublic void updateAvatar(String avatarUrl){Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");userMapper.updateAvatar(avatarUrl,id);}@Overridepublic void updatePwd(String newPwd){Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);}

Mapper层(UserMapper.java)

@Update("update user set nickname=#{nickname},email=#{email},update_time=#{updateTime} where id=#{id}")void update(User user);@Update("update user set user_pic=#{avatarUrl},update_time=now() where id=#{id}")void updateAvatar(String avatarUrl, Integer id);@Update("update user set password=#{md5String},update_time=now() where id=#{id}")void updatePwd(String md5String, Integer id);

更改密码后Jwt令牌的及时失效

需要用到Redis服务。

Redis是一个开源的、基于内存的数据结构存储系统,可以用作数据库、缓存和消息代理。

作为缓存存储系统非常流行,可以将经常访问的数据存储在内存中,以加快读取速度,减轻后端数据库的负载。可用于存储会话数据,以实现分布式会话管理,提高可扩展性和性能。

首先从github上下载redis

Releases · tporadowski/redis · GitHub

解压后cd命令切换至根目录下启动,看到下面的界面

redis-server.exe redis.windows.conf

然后在pom.xml中添加下面的字段

<!--redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

将application.yml修改为如下

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/big_eventusername: rootpassword: rootdata:redis:host: localhostport: 6379mybatis:configuration:map-underscore-to-camel-case: true #开启驼峰命名和下划线命名的自动转换

针对Redis需要做出的修改:登录成功后需要将token储存至Redis中,系统内页面在访问时验证需要从Redis中获取token,密码更新后需要删除Redis中对应的token。

修改UserController.java中的内容

@Autowiredprivate StringRedisTemplate stringRedisTemplate;
@PostMapping("/login")public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password){//根据用户名查询用户User loginUser = userService.findByUserName(username);//判断该用户是否存在if (loginUser==null){return Result.error("用户名不存在");}//判断密码是否正确,传入参数加密后与数据库中的密文进行比对if (Md5Util.getMD5String(password).equals(loginUser.getPassword())) {//登录成功Map<String,Object> claims = new HashMap<>();claims.put("id",loginUser.getId());claims.put("username",loginUser.getUsername());String token = JwtUtil.genToken(claims);//把token存储到redis中ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.set(token,token, 1, TimeUnit.HOURS);return Result.success(token);}return Result.error("密码错误");}

 @PatchMapping("/updatePwd")public Result updatePwd(@RequestBody Map<String, String> params,@RequestHeader("Authorization") String token){//校验参数String oldPwd = params.get("old_pwd");String newPwd = params.get("new_pwd");String rePwd = params.get("re_pwd");if (!StringUtils.hasLength(oldPwd)|| !StringUtils.hasLength(newPwd)|| !StringUtils.hasLength(rePwd)){return Result.error("缺少必要的参数");}//原密码是否正确,调用原密码和old_pwd进行比较Map<String, Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User loginUser = userService.findByUserName(username);if(!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))){return Result.error("原密码错误");}if(!rePwd.equals(rePwd)){return Result.error("两次填写的密码不一致");}//调用service完成密码更新userService.updatePwd(newPwd);//删除redis中对应的tokenValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.getOperations().delete(token);return Result.success("密码修改成功");}

修改LoginInterceptor.java中的内容

    @Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//令牌验证String token = request.getHeader("Authorization");//验证tokentry {//从redis中获取相同的tokenValueOperations<String, String> operations = stringRedisTemplate.opsForValue();String redisToken = operations.get(token);if (redisToken==null){throw new RuntimeException();}Map<String, Object> claims = JwtUtil.parseToken(token);//把业务数据储存到ThreadLocal中ThreadLocalUtil.set(claims);//放行return true;} catch (Exception e) {response.setStatus(401);//不放行return false;}

SpringBoot项目部署

SpringBoot项目在后端程序员电脑上正常运行之后,就需要打包上传至公司服务器,进行项目部署。

在pom.xml中 <dependecies>和</project>之间添加下面的字段用于打包

<build><plugins><!--打包操作--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.2.3</version></plugin></plugins></build>

在右侧边栏找到package字样,点击运行等程序跑完。

这里需要注意的是:SpringBoot在进行自动化打包的时候,是会默认测试Test环境下的java类能否正常运行的。要么在打包的时候选择skip跳过,要么就确保测试类能够正常运行。

如果配置了Redis那么也同时需要把redis打开。

还有就是打包的时候要把项目关了,不然就会报错8080端口占用。

可以看到已经打包成功了,这里就不上传服务器,假设本地Windows电脑为服务端进行测试

jdk需要至少版本17,找到打包好的jar包,直接java -jar system-1.0-SNAPSHOT.jar启动

由于还没有编写前端页面,所以还是只能通过Apifox来进行试验,这里就进行演示了。

结束

其实还有一些比如说多环境(测试,开发,生产)下的开发,本地电脑属性的配置等等内容没有介绍,但由于是小项目没有这个必要,所以也就不进行过多的赘述了。

关于后端系统开发的专栏就暂且告一段落了。

尾声

后面开始就要进行Vue.js的工程化部署以及前后端的连接了,大家可以点个关注跟进一下。

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

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

相关文章

安达发|电子产品制造企业APS生产排程软件

在电子脉动的世界中&#xff0c;时间是芯片上的电流&#xff0c;效率是电路板上的速度。在这个时代&#xff0c;每一微秒都蕴藏着无限可能&#xff0c;每一决策都关乎着企业的生死存亡。APS生产排程软件&#xff0c;是您的电子制造帝国中的智慧大脑&#xff0c;以卓越的创造力&…

Reactor设计模式和Reactor模型

Reactor设计模式 翻译过来就是反应堆&#xff0c;所以Reactor设计模式本质是基于事件驱动。 角色 Handle&#xff08;事件&#xff09;EventHandler&#xff08;事件处理器&#xff09;ConcreteEventHandler&#xff08;具体事件处理器&#xff09;Synchronous Event Demult…

CTR之Session行为序列建模用户兴趣:DSIN

在前面的文章中&#xff0c;DIN模型 在用户行为序列建模中引入注意力机制来强调加权与target item相关的行为&#xff0c;以实现动态的兴趣表征&#xff1b;而DIEN模型 则在DIN的基础上加入时间性信息&#xff0c;使用注意力机制的GRU来挖掘用户兴趣的演变。 而今天的这篇文章…

jspssm_maven项目——KTV点歌系统

目录 背景 技术简介 系统简介 界面预览 背景 随着互联网的广泛渗透和进步&#xff0c;基于网络技术的KTV点歌系统迅速壮大&#xff0c;其发展始终围绕用户的实际需求展开。通过深入洞察用户的需求&#xff0c;开发出高度定制的管理平台&#xff0c;利用网络的便捷性对系统…

8.软件工程

整个章节偏向于记忆、背诵&#xff1b; 主要议题&#xff1a; 软件体系&#xff1a;3层&#xff1b; UML重点&#xff0c;重点记3要素中的关系、图&#xff1b; 1.软件体系结构 分层 优点&#xff1a;利于软件的重复利用&#xff1b; 缺点&#xff1a;以什么方式分层&#…

使用Urllib库创建第一个爬虫程序

Urllib 是 Python 的标准库&#xff0c;它提供了一系列用于处理 URL 的函数和类&#xff0c;包括发送 HTTP 请求、处理 HTTP 响应、解析 URL 等功能。可以使用 urllib 来编写简单的网络爬虫。 request&#xff1a;它是最基本的HTTP请求模块&#xff0c;可以用来模拟发送请求。只…

【JavaScript 漫游】【044】Web Worker

文章简介 本篇文章为【JavaScript 漫游】专栏的第 044 篇文章&#xff0c;对浏览器模型的 Web Worker 相关知识点进行了总结。 概述 JavaScript 语言采用的是单线程模型&#xff0c;也就是说&#xff0c;所有任务只能在一个线程上完成&#xff0c;一次只能做一件事。前面的任…

MySQL 8.0.35 企业版开启审计audit log功能

一、系统环境和要求 在MySQL中&#xff0c;开启日志审计可以记录数据库的操作日志&#xff0c;包括修改、删除、插入等操作。这对于追踪和分析数据库的使用情况以及排查潜在的安全问题非常有帮助。本文将详细介绍如何开启MySQL的日志审计功能。 操作系统&#xff1a;Ubuntu 20…

人工智能 框架 paddlepaddle 飞桨 使用指南 使用例子 线性回归模型demo 1

安装过程&使用指南&线性回归模型 使用例子 本来预想 是安装 到 conda 版本的 11.7的 但是电脑没有gpu 所以 安装过程稍有变动,下面简单讲下 conda create -n paddle_env117 python=3.9 由于想安装11.7版本 py 是3.9 所以虚拟环境名称也是 paddle_env117 activa…

6 Spring-AOP

文章目录 1&#xff0c;AOP简介1.1 什么是AOP?1.2 AOP作用1.3 AOP核心概念 2&#xff0c;AOP入门案例2.1 需求分析2.2 思路分析2.3 环境准备2.4 AOP实现步骤步骤1:添加依赖步骤2:定义接口与实现类步骤3:定义通知类和通知步骤4:定义切入点步骤5:制作切面步骤6:将通知类配给容器…

常用设计模式介绍

前言 简说设计模式。 文章目录 前言一、设计模式的要素1、设计模式解决的问题2、设计模式分类1&#xff09;创建型设计模式2&#xff09;结构型设计模式3&#xff09;行为型设计模式 二、详细介绍1、创建型设计模式1&#xff09;工厂方法模式2&#xff09;抽象工厂模式3&#x…

基于FPGA的光纤通信系统设计

文章目录 光纤通信系统的组成发送端FPGA端口定义状态机设计代码示例 接收端功能模块端口定义状态机设计 光纤通信系统的组成 发送端FPGA 发送控制逻辑、数据编码、校验码生成、缓存控制、时钟控制 端口定义 状态机设计 代码示例 接收端功能模块 接收端控制逻辑、数据解码、…

谈谈伦敦银投资的价值吗?

白银作为贵金属家族中的一员&#xff0c;当然有着其自身的经济价值和投资价值&#xff0c;尤其是在通货膨胀或货币贬值的时候&#xff0c;伦敦银的价格往往会上涨&#xff0c;投资者参与其中就能起到保值增值的作用。 此外&#xff0c;白银还是一种很好的避险资产&#xff0c;…

港大新工作 HiGPT:一个模型,任意关系类型 !

论文标题&#xff1a; HiGPT: Heterogeneous Graph Language Model 论文链接&#xff1a; https://arxiv.org/abs/2402.16024 代码链接&#xff1a; https://github.com/HKUDS/HiGPT 项目网站&#xff1a; https://higpt-hku.github.io/ 1. 导读 异质图在各种领域&#xf…

Linux系统下安装部署Linux管理面板1panel

目录 一 1panel介绍 1、1Panel简介 2、1Panel特点 二、本地环境规划 1、本此实验目的 2、本地环境部署 三、部署1Panel&#xff08;在线安装&#xff09; 1.创建安装目录 2.一键部署1Panel 3.检查1Panel服务运行状态 4.检查1Panel监听端口 四、关闭防火墙和selinux…

zabbix进阶

知识点补充 zabbix server在主机上运行服务&#xff0c;端口号为10050&#xff0c;zabbix agent 在被监控机器上运行&#xff08;源码下载&#xff09;主要完成对cpu&#xff0c;磁盘的信息采集&#xff0c;端口号为10051 zabbix 软件结构组成&#xff1a; 1.Zabbix Web GUI …

leetcode 107.二叉树的层序遍历II

题目 思路 正常层序遍历输出&#xff1a; [[3],[9,20],[15,7]] 这道题要求的输出&#xff1a;[[15,7],[9,20],[3]] 可以观察到&#xff0c;只要我们把原来的结果reverse一下就行了。 代码 //leetcode submit region begin(Prohibit modification and deletion)import java…

HWY-41B无源静态电压继电器 整定范围19-240VAC导轨安装JOSEF约瑟

HWY-31A无辅源静态电压继电器 HWY-32A无辅源静态电压继电器 HWY-33A无辅源静态电压继电器 HWY-34A无辅源静态电压继电器 HWY-35A无辅源静态电压继电器 HWY-31B无辅源静态电压继电器 HWY-32B无辅源静态电压继电器 HWY-33B无辅源静态电压继电器 HWY-34B无辅源静态电压继电器 HW…

激活函数选得好,模型性能差不了!17个方法,让网络训练更高效

激活函数是神经网络中不可或缺的组成部分&#xff0c;它们通过引入非线性特性&#xff0c;增强了网络的表达能力和学习能力。常用的激活函数主要可以分为两大类&#xff1a;饱和激活函数、非饱和激活函数。其中sigmoid和tanh是饱和激活函数&#xff0c;而ReLU及其变体则是非饱和…

程序员35岁会失业吗?【来自主流AI的回答】

程序员35岁会失业吗&#xff1f; 35岁被认为是程序员职业生涯的分水岭&#xff0c;许多程序员开始担忧自己的职业发展是否会受到年龄的限制。有人担心随着年龄的增长&#xff0c;技术更新换代的速度会使得资深程序员难以跟上&#xff1b;而另一些人则认为&#xff0c;丰富的经…