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

原文地址: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)

    @Override
    public void update(User user){
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    public void updateAvatar(String avatarUrl){
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        userMapper.updateAvatar(avatarUrl,id);
    }

    @Override
    public 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.Driver
    url: jdbc:mysql://localhost:3306/big_event
    username: root
    password: root
  data:
    redis:
      host: localhost
      port: 6379

mybatis:
  configuration:
    map-underscore-to-camel-case: true #开启驼峰命名和下划线命名的自动转换

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

修改UserController.java中的内容

@Autowired
    private 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中对应的token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return Result.success("密码修改成功");
    }

修改LoginInterceptor.java中的内容

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //令牌验证
        String token = request.getHeader("Authorization");
        //验证token
        try {
            //从redis中获取相同的token
            ValueOperations<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的工程化部署以及前后端的连接了,大家可以点个关注跟进一下。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

监控系统Prometheus--入门

文章目录 Prometheus特点易于管理监控服务的内部运行状态强大的数据模型强大的查询语言PromQL高效可扩展易于集成可视化开放性 Prometheus架构Prometheus 生态圈组件架构理解 Prometheus的安装安装Prometheus Server上传安装包解压安装包修改配置文件 prometheus.yml 安装Pushg…

linux下docker容器的使用

1、根据已有镜像images创建容器 1.1、查看镜像 如果是接手的别人的项目&#xff0c;需要从以往的images镜像中创建新容器&#xff0c;使用命令查看当前机器上的docker镜像&#xff1a; docker images1.2、创建容器 使用docker run 根据images镜像名创建容器&#xff0c;命令…

查看Scala类的方法

文章目录 一、概述如何查看Scala类的方法二、使用Scala文档查看类的方法三、使用反射机制查看类的方法 一、概述如何查看Scala类的方法 本文介绍了在Scala中查看Int类方法的两种方法&#xff1a;使用Scala标准库文档和使用反射机制。通过Scala标准库文档&#xff0c;您可以方便…

[Netty实践] 请求响应同步实现

目录 一、介绍 二、依赖引入 三、公共部分实现 四、server端实现 五、client端实现 六、测试 一、介绍 本片文章将实现请求响应同步&#xff0c;什么是请求响应同步呢&#xff1f;就是当我们发起一个请求时&#xff0c;希望能够在一定时间内同步&#xff08;线程阻塞&am…

操作系统面经-用户态和内核态

字节实习生带你面试&#xff0c;后台私信可以获得面试必过大法&#xff01;&#xff01; 根据进程访问资源的特点&#xff0c;我们可以把进程在系统上的运行分为两个级别&#xff1a; 用户态(User Mode) : 用户态运行的进程可以直接读取用户程序的数据&#xff0c;拥有较低的…

启动Vue-demo时引发的一系列问题—解决办法

目录 1.初始遇到的问题&#xff1a;输入npm run dev 1.治标的解决方法 2.治本的解决方法 第一步&#xff1a;检查是否安装了cnpm 第二步&#xff1a;手动找到cnpm目录 第三步&#xff1a;配置系统环境变量 第四步&#xff1a;查看是否安装成功 1.初始遇到的问题&#xf…

JavaSE:类与对象

目录 一、前言 二、类与对象的介绍 1.类的定义格式 三、类的实例化 1.类的实例化介绍 2.成员初始化 3.类中方法的实现 四、封装 1.private实现封装 2.getter和setter方法 五、构造方法的使用 1.构造方法的介绍 2.构造方法的特性 六、this引用 1.this的介绍 2.th…

LeetCode---126双周赛

题目列表 3079. 求出加密整数的和 3080. 执行操作标记数组中的元素 3081. 替换字符串中的问号使分数最小 3082. 求出所有子序列的能量和 一、求出加密整数的和 按照题目要求&#xff0c;直接模拟即可&#xff0c;代码如下 class Solution { public:int sumOfEncryptedInt…

Oracle Data Guard常用命令

--查询数据库角色和保护模式 select database_role,switchover_status from v$database; --切换备库为主库&#xff08;切换后&#xff0c;主库为mount状态&#xff09; --TO PRIMARY alter database commit to switchover to primary; --SESSIONS ACTIVE alter database comm…

如何保障消息一定能发送到RabbitMQ?

我们知道&#xff0c;RabbitMQ的消息最终是存储在Queue上的&#xff0c;而在Queue之前还要经过Exchange&#xff0c;那么这个过程中就有两个地方可能导致消息丢失。第一个是Producer到Exchange的过程&#xff0c;第二个是Exchange到Queue的过程。 为了解决这个问题&#xff0c…

大学期末考试搜题软件?这4款足够解决问题 #知识分享#笔记#职场发展

当代大学生面临着繁重的学业压力和海量的知识点&#xff0c;如何高效地进行学习和搜题成了他们关注的焦点。幸运的是&#xff0c;随着科技的不断进步&#xff0c;我们有越来越多的日常搜题和学习软件可以帮助我们更好地应对这些挑战。在本文中&#xff0c;我将为大家介绍10款备…

皓学IT:WEB06_ EL表达式JSTL标签库

一、EL表达式 1.1.特点 是一个由java开发的工具包 用于从特定域对象中读取并写入到响应体开发任务&#xff0c;不能向域对象中写入。 EL工具包自动存在Tomcat的lib中&#xff08;el-api.jar&#xff09;&#xff0c;开发是可以直接使用&#xff0c;无需其他额外的包。 标准…

千万不要错过这9款能让你快速写作成长的宝藏软件…… #科技#学习方法#学习

很多小伙伴想要自己做自媒体&#xff0c;但是却不知道从何下手&#xff0c;今天我就和大家分享一波好用的一些自媒体工具。 1.红桃写作 这是一个微信公众号 面向专业写作领域的ai写作工具&#xff0c;写作助手包括&#xff0c;ai论文,ai开题报告、ai公文写作、ai商业计划书、…

每日五道java面试题之springboot篇(三)

目录&#xff1a; 第一题. Spring Boot 中的监视器是什么&#xff1f;第二题. 如何在 Spring Boot 中禁用 Actuator 端点安全性&#xff1f;第三题. 我们如何监视所有 Spring Boot 微服务&#xff1f;第四题. 什么是 WebSockets&#xff1f;第五题. 什么是 Spring Data ? 第一…

Qt教程 — 3.6 深入了解Qt 控件:Display Widgets部件(2)

目录 1 Display Widgets简介 2 如何使用Display Widgets部件 2.1 QTextBrowser组件-简单的文本浏览器 ​2.2 QGraphicsView组件-简单的图像浏览器 Display Widgets将分为两篇文章介绍 文章1&#xff08;Qt教程 — 3.5 深入了解Qt 控件&#xff1a;Display Widgets部件-CSDN…

使用POI以OLE对象的形式向excel中插入附件(pdf为例)

前言&#xff1a; 最近在使用easyExcel操作excel文件时&#xff0c;一直想找到一个方法可以往excel中填充附件&#xff0c;但是目前只发现POI可以插入附件&#xff0c;于是将方法记录如下&#xff1a; 实现&#xff1a; 这个方法主要是使用 Apache POI 的 HSSFWorkbook 类来…

带有GUI界面的电机故障诊断(MSCNN-BILSTM-ATTENTION模型,TensorFlow框架,有中文注释,带有六种结果可视化)

本次创作最主要是在MSCNN-BILSTM-ATTENTION模型&#xff08;可轻松替换为其它模型&#xff09;基础上&#xff0c;搭建GUI测试界面&#xff0c;方便对你想要测试的数据的进行测试&#xff0c;同时进行了全面的结果可视化&#xff1a;1.训练集和测试集的准确率曲线&#xff0c;2…

第28章 ansible的使用

第28章 ansible的使用 本章主要介绍在 RHEL8 中如何安装 ansible 及 ansible的基本使用。 ◆ ansible 是如何工作的 ◆ 在RHEL8 中安装ansible ◆ 编写 ansible.cfg 和清单文件 ◆ ansible 的基本用法 文章目录 第28章 ansible的使用28.1 安装ansible28.2 编写ansible.cfg和清…

v3-admin-vite 整合pont

需求 目前后端的Admin模板使用的是v3-admin-vite&#xff0c;需要整合pont接口&#xff0c;方便前后端统一一体化开发 安装PONT 按照官方的文档&#xff0c;将pont engine安装好&#xff0c;然后在项目根目录执行pont start。注意生成代码路径要修改一下&#xff0c;因为v3-a…

AI新工具(20240322) 免费试用Gemini Pro 1.5;先进的AI软件工程师Devika;人形机器人Apptronik给你打果汁

✨ 1: Gemini Pro 1.5 免费试用Gemini Pro 1.5 Gemini 1.5 Pro是Gemini系列模型的最新版本&#xff0c;是一种计算高效的多模态混合专家&#xff08;MoE&#xff09;模型。它能够从数百万个上下文Token中提取和推理细粒度信息&#xff0c;包括多个长文档和数小时的视频、音频…