
【Springboot3vue3】从零到一搭建Springboot3vue3前后端分离项目整合knef4j和mybaits实现基础用户信息管理*后端环境搭建* * 1.1 环境准备 * 1.2 数据库表准备 * 1.3 SpringBoot3项目创建 * 1.4 MySql环境整合使用druid连接池 * 1.5 整合mybatis-plus * * 1.5.1 引入mybaties-plus * 1.5.2 配置代码生成器 * 1.5.3 配置分页插件 * 1.6 整合swagger3knife4j * * 1.6.1 整合 * 1.6.2 使用 * 1.7 数据交互处理 * * 1.7.1响应数据封装公共返回数据类 * 1.7.2 分页查询返回数据封装 * 1.8 全局异常处理 * 1.9 整合JWT,生成token * 1.10 封装ThreadLocal工具类 * 1.11 MD5封装 * 1.12 登陆验证拦截 * 1.13 新增登录和查询当前用户 * * 1.13.1 新增用户 * 1.13.2 用户登录 * 1.13.3 获取当前用户信息 * 1.13.4 查询所有用户信息 * 1.14 删除和修改用户信息 * * 1.14.1 删除用户信息 * 1.14.2 修改用户信息 跟着黑马敲了黑马点评和苍穹外卖但是感觉黑马教程封装的太好了。于是想自己从零到一搭建一个前后端分离的简单项目。 主要参考的博客为从零搭建SpringBoot3Vue3前后端分离项目基座中小项目可用_springbootvue3-CSDN博客记录一下自己的实现过程。最终实现效果如下后端环境搭建------### 1.1 环境准备-spring-boot3 最低支持jdk17所以需要准备jdk17的环境-Idea版本 2024.1.4-Mysql8### 1.2 数据库表准备可以随便使用一个数据库可视化软件然后创建数据库data_demo,并运行以下查询创建用户表我用的是Navicat Premium建好后选中数据库右键选择新建查询运行如下命令创建数据库表 CREATE TABLE user( id INT NOT NULL AUTO_INCREMENT COMMENT ‘主键’, login_name VARCHAR(255) NOT NULL COMMENT ‘登录名账号’, password VARCHAR(255) NOT NULL COMMENT ‘密码’, name varchar(50) NOT NULL COMMENT ‘姓名’, sex char(1) NOT NULL COMMENT ‘性别’, phone VARCHAR(20) COMMENT ‘联系电话’, PRIMARY KEY(id) )COMMENT ‘用户信息表’; ### 1.3 SpringBoot3项目创建之后等待项目构建完成。构建完成的pom.xml文件如下注意我在这里修改了spring的version修改为3.3.3 因为在后面集成knef4j的时候发现3.4.0版本的spring无法显示接口。 参考博客如下 尚硅谷新SSM教程中关于Knife4j 接口文档无法显示接口的问题_knife4j 识别不到controller-CSDN博客 即正确的启动控制台没问题但是不显示接口信息后面将spring的版本降为3.3.3成功解决 ?xml version1.0 encodingUTF-8? 4.0.0 org.springframework.boot spring-boot-starter-parent 3.3.3 com.myProject demo 0.0.1-SNAPSHOT demo demo java.version17/java.version org.springframework.boot spring-boot-starter-web com.mysql mysql-connector-j runtime org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ### 1.4 MySql环境整合使用druid连接池在pom.xml中添加jdbc依赖防止项目启动时找不到Bean报错 org.springframework.boot spring-boot-starter-jdbc 添加druid依赖 com.alibaba druid-spring-boot-3-starter 1.2.20 项目使用yml格式配置文件修改resources下的application.properties为application.yml删除文件原本内容并将application.yml文件内容加上如下 配置项目端口号 server: port: 9999 在application.yml中配置数据源和druid连接池 ,注意将database的name修改为自己数据库的名称以及mysql的username和password # ??? database: name: data_demo spring: datasource: #??? url: jdbc:mysql://localhost:3306/${database.name}?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/Shanghai username: root password: root 启动项目 查看日志端口和druid 初始化 整合成功### 1.5 整合mybatis-plus#### 1.5.1 引入mybaties-plus官网地址 https://baomidou.com/1. pom.xml中添加如下依赖 com.baomidou mybatis-plus-spring-boot3-starter 3.5.5 2. application.yml中加入如下配置 # mybatis ??? mybatis-plus: configuration: #??? map-underscore-to-camel-case: true mapper-locations: classpath:mapper/.xml type-aliases-package: com.example.demo 启动项目出现mybatis-plus日志#### 1.5.2 配置代码生成器1. pom.xml中添加如下依赖 com.baomidou mybatis-plus-generator 3.5.5 org.springframework.boot spring-boot-starter-freemarker 2.新建utils包并在下边创建MybatisPlusGenerator.java代码生成器配置类package com.example.demo.utils; import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.OutputFile; import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.io.File; import java.sql.Types; import java.util.Collections; public class MybatisPlusGenerator { static final String url “jdbc:mysql://127.0.0.1:3306/data_demo?serverTimezoneUTC”; // 数据库地址 static final String username “root”; // 数据库用户名 static final String password “123456”; // 数据库密码 static final String authorName “HuaXiang”; // 作者名 static final String parentPackageNameResource “com/example/demo”; // mapper.xml路径 static final String parentPackageNameJava “com.example.demo”; // java 文件父包名 // 要生成代码对应的数据表名 static final String tableName “user”; public static void main(String[] args) { FastAutoGenerator.create(url, username, password) // 1.全局配置 .globalConfig(builder - { builder.author(authorName) // 设置作者 .enableSpringdoc() // 开启 swagger 模式 // 获取当前工程路径并定位到项目java目录下 .outputDir(System.getProperty(“user.dir”) “/src/main/java”); // 指定输出目录 }) // 2.数据源配置 .dataSourceConfig(builder - builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) - { int typeCode metaInfo.getJdbcType().TYPE_CODE; if (typeCode Types.SMALLINT) { // 自定义类型转换 return DbColumnType.INTEGER; } return typeRegistry.getColumnType(metaInfo); })) // 3.包名策略配置 .packageConfig(builder - { builder.parent(parentPackageNameJava) // 设置父包名 .entity(“entity”) .mapper(“mapper”) .service(“service”) .serviceImpl(“service.impl”) .controller(“controller”) //.moduleName(“system”) // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty(“user.dir”) “/src/main/resources/” “/mapper”)); // 设置mapperXml生成路径 }) // 策略配置 .strategyConfig(builder - { builder.addInclude(tableName) // 设置需要生成的表名 // 覆盖已生成文件 .entityBuilder().enableFileOverride() .mapperBuilder().enableFileOverride() .serviceBuilder().enableFileOverride().formatServiceFileName(“%sService”); //.addTablePrefix(“t_”, “c_”); // 设置过滤表前缀 }) // 配置模板 .templateConfig(builder - { //builder.controller(“”); // 不生成controller }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板默认的是Velocity引擎模板 .execute(); } } * 修改数据库相关信息修改authorName* 修改parentPackageNameResource parentPackageNameJava* 修改tableName 要生成代码的数据表名称多个表使用分割* .enableSpringdoc() 可以选择生成swagger3文档注释 修改完成后运行main函数生成相应代码mapper.xml在resource下与java同路径下运行后目录如下#### 1.5.3 配置分页插件新建config包并在下边配置类MybatiesPlusConfig.javapackage com.example.demo.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MybatisPlusConfig { /** * 添加分页插件/ Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加 //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType return interceptor; } } 在启动类配置扫描mapper路径MapperScan(“com.example.demo.mapper”)### 1.6 整合swagger3knife4j#### 1.6.1 整合1. pom.xml引入knife4j的依赖 com.github.xiaoymin knife4j-openapi3-jakarta-spring-boot-starter 4.5.0 2. application.yml中添加配置 # springdoc-openapi 配置 springdoc: swagger-ui: path: /swagger-ui.html tags-sorter: alpha operations-sorter: alpha api-docs: path: /v3/api-docs group-configs: - group: ‘default’ paths-to-match: /’ packages-to-scan: com.example.demo.controller # knife4j 配置 knife4j: # 是否启用增强 enable: true # 开启生产环境屏蔽 production: false # 是否认证登录 basic: # basic是否开启默认为false enable: true username: root password: 123456 setting: language: zh_cn enable-version: true enable-swagger-models: true 3. 测试。配置完成后访问路径http://localhost:9999/doc.html 用户名密码为配置文件中的用户名和密码如图#### 1.6.2 使用实体类使用Schema注解在mybatis-plus选择的话会自动生成Controller层使用 /** 用户信息表 前端控制器 ** since 2024-12-06/ Tag(name “用户接口”) RestController RequestMapping(“/user”) public class UserController { Autowired private UserService userService; /* 用户列表分页 * param pageSize 每页显示的条数 * param currentPage 要查询的页 * param name 用户姓名 * return ResultPageResultBeanList/ GetMapping(“/pageList”) Operation(summary “用户列表分页查询”) Parameters({ Parameter(name “Authorization”, in ParameterIn.HEADER, required true, description “token”), Parameter(name “pageSize”, required true, description “每页显示的条数”), Parameter(name “currentPage”, required true, description “要查询的页”), Parameter(name “name”, description “用户姓名”, required false) }) public ResultPageResultBean pageList(RequestParam int pageSize, RequestParam int currentPage, Nullable RequestParam String name) { IPage page userService.pageList(pageSize, currentPage, name); if (page null) { return Result.error(“查询失败”); } //PageResultBean pageResultBean new PageResultBean(page.getTotal(), page.getRecords()); return Result.success(PageResultBean.getInstance(page.getTotal(), page.getRecords())); } }### 1.7 数据交互处理#### 1.7.1响应数据封装公共返回数据类封装返回数据封装类放到common包下package com.example.demo.common; import io.swagger.v3.oas.annotations.media.Schema; public class Result { Schema(description “业务状态码 1成功 0: 失败”) private int code; // 业务状态码 0成功 1: 失败 Schema(description “提示信息”) private String message; // 提示信息 Schema(description “返回数据”) private T data; // 响应数据 public Result(int code, String message, T data) { this.code code; this.message message; this.data data; } // 操作成功返回响应结果带响应数据 public static Result success(E data) { return new Result(1, “操作成功”, data); } public static Result success() { return new Result(1, “操作成功”, null); } public static Result error(String message) { return new Result(0, message, null); } public int getCode() { return code; } public void setCode(int code) { this.code code; } public String getMessage() { return message; } public void setMessage(String message) { this.message message; } public T getData() { return data; } public void setData(T data) { this.data data; } Override public String toString() { return “Result{” “code” code “, message” message ‘’’ “, data” data ‘}’; } } #### 1.7.2 分页查询返回数据封装封装分页查询的数据放到common包下package com.example.demo.common; import io.swagger.v3.oas.annotations.media.Schema; public class Result { Schema(description “业务状态码 0成功 1: 失败”) private int code; // 业务状态码 0成功 1: 失败 Schema(description “提示信息”) private String message; // 提示信息 Schema(description “返回数据”) private T data; // 响应数据 public Result(int code, String message, T data) { this.code code; this.message message; this.data data; } // 操作成功返回响应结果带响应数据 public static Result success(E data) { return new Result(0, “操作成功”, data); } public static Result success() { return new Result(0, “操作成功”, null); } public static Result error(String message) { return new Result(1, message, null); } public int getCode() { return code; } public void setCode(int code) { this.code code; } public String getMessage() { return message; } public void setMessage(String message) { this.message message; } public T getData() { return data; } public void setData(T data) { this.data data; } Override public String toString() { return “Result{” “code” code “, message” message ‘’’ “, data” data ‘}’; } } ### 1.8 全局异常处理创建exception包在包下放全局异常处理类GlobalExceptionHandler.java,使用springboot RestControllerAdvice注解配置 package com.example.demo.exception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import com.example.demo.common.Result; // 全局异常处理 RestControllerAdvice public class GlobalExceptionHandler { private final Logger logger LoggerFactory.getLogger(GlobalExceptionHandler.class); ExceptionHandler(Exception.class) public Result handlerException(Exception e) { logger.warn(e.getMessage()); return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : “操作失败”); } } ### 1.9 整合JWT,生成token1. pom.xml 中引入依赖 com.auth0 java-jwt 4.4.0 2. 封装工具类JwtUtil放到utils包下 package com.example.demo.utils; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import java.util.Date; import java.util.Map; public class JwtUtil { private static final String KEY “Demo”; // 密钥 // 接收数据生成token并返回 public static String getToken(MapString, Object claims) { return JWT.create() .withClaim(“claims”, claims) .withExpiresAt(new Date(System.currentTimeMillis() 1000 * 60 * 60)) // 失效时间1小时 .sign(Algorithm.HMAC256(KEY)); } // 接收token,验证并返回数据 public static MapString, Object parseToken(String token) { return JWT.require(Algorithm.HMAC256(KEY)) .build() .verify(token) .getClaim(“claims”) .asMap(); } } ### 1.10 封装ThreadLocal工具类因为前后端分离使用ThreadLocal线程变量存储用户登录信息替代session package com.example.demo.utils; public class ThreadLocalUtil { // 提供ThreadLocal 对象 private static final ThreadLocal THREAD_LOCAL new ThreadLocal(); // 获取存储值 public static T get() { return (T) THREAD_LOCAL.get(); } // 存储值 public static void set(Object value) { THREAD_LOCAL.set(value); } // 清除THREAD_LOCAL 防止内存泄漏 public static void remove() { THREAD_LOCAL.remove(); } } ### 1.11 MD5封装 package com.example.demo.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Md5Util { /* * 默认的密码字符串组合用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合/ protected static char hexDigits[] {‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’}; protected static MessageDigest messagedigest null; static { try { messagedigest MessageDigest.getInstance(“MD5”); } catch (NoSuchAlgorithmException nsaex) { System.err.println(Md5Util.class.getName() “初始化失败MessageDigest不支持MD5Util。”); nsaex.printStackTrace(); } } /* * 生成字符串的md5校验值 * * param s * return/ public static String getMD5String(String s) { return getMD5String(s.getBytes()); } /* * 判断字符串的md5校验码是否与一个已知的md5码相匹配 * * param password 要校验的字符串 * param md5PwdStr 已知的md5校验码 * return/ public static boolean checkPassword(String password, String md5PwdStr) { String s getMD5String(password); return s.equals(md5PwdStr); } public static String getMD5String(byte[] bytes) { messagedigest.update(bytes); return bufferToHex(messagedigest.digest()); } private static String bufferToHex(byte bytes[]) { return bufferToHex(bytes, 0, bytes.length); } private static String bufferToHex(byte bytes[], int m, int n) { StringBuffer stringbuffer new StringBuffer(2 * n); int k m n; for (int l m; l k; l) { appendHexPair(bytes[l], stringbuffer); } return stringbuffer.toString(); } private static void appendHexPair(byte bt, StringBuffer stringbuffer) { char c0 hexDigits[(bt 0xf0) 4];// 取字节中高 4 位的数字转换, // 为逻辑右移将符号位一起右移,此处未发现两种符号有何不同 char c1 hexDigits[bt 0xf];// 取字节中低 4 位的数字转换 stringbuffer.append(c0); stringbuffer.append(c1); } // 测试 public static void main(String[] args) { System.out.println(Md5Util.getMD5String(“admin”)); } } ### 1.12 登陆验证拦截1. 创建包interceptors在包下配置登录拦截器 package com.example.demo.interceptors; import com.example.demo.utils.JwtUtil; import com.example.demo.utils.ThreadLocalUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import java.util.Map; Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取token String token request.getHeader(“Authorization”); // 验证token try { MapString, Object claims JwtUtil.parseToken(token); // 存储业务信息到线程变量 ThreadLocalUtil.set(claims); // 放行拦截 return true; } catch (Exception e) { // 登录信息异常或未登录http响应状态码为401 response.setStatus(401); // 拦截请求 return false; } } Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 清除ThreadLocal业务数据 ThreadLocalUtil.remove(); } } 2. 在config包下创建WebConfig配置类注册登录拦截器 package com.example.demo.config; import com.example.demo.interceptors.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.ArrayList; import java.util.List; Configuration public class WebConfig implements WebMvcConfigurer { Autowired private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { // 配置放行资源 // 无需拦截的接口集合 List ignorePath new ArrayList(); // knife4j(swagger) ignorePath.add(“/swagger-resources/“); ignorePath.add(”/doc.html); ignorePath.add(/v3/”); ignorePath.add(“/webjars/“); ignorePath.add(”/static/”); ignorePath.add(/templates/“); ignorePath.add(”/error); // 登录页面 ignorePath.add(“/user/login”); ignorePath.add(“/user/add”); registry.addInterceptor(loginInterceptor).excludePathPatterns(ignorePath); } } ### 1.13 新增登录和查询当前用户#### 1.13.1 新增用户逻辑为1. 参数验证。对传入的user进行基本的非空校验校验用户姓名登录名以及密码是否为空或者null。为空则返回错误提示信息2. 用户名重复校验。通过userService中的findByLoginName去数据库中查询是否存在相同loginName的用户3. 密码非空判断假如密码为空设置为默认的1234564. 密码加密处理。使用1.11 中的MD5对数据库中的密码进行加密5. 保存用户信息到数据库调用userService中的add方法。在UserController.java中加入如下方法 /* 添加用户 * param User * return Result/ PostMapping(“/add”) Operation(summary “添加用户”) Parameter(name “Authorization”, in ParameterIn.HEADER, required true, description “token”) public Result addUser(RequestBody User user) { return userService.add(user); } 在UserService.java中加入如下方法 Result add(User user); UserServiceImpl.java中 package com.example.demo.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.service.UserService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.demo.utils.Md5Util; import org.springframework.stereotype.Service; /** 用户信息表 服务实现类 ** * author HuaXiang * since 2024-12-06/ Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService { private final UserMapper userMapper; public UserServiceImpl(UserMapper userMapper) { this.userMapper userMapper; } public IPage pageList(int pageSize, int currentPage, String name) { // 创建Page对象传入当前页码和每页显示的记录数 Page page new Page(currentPage, pageSize); // 可以在这里添加条件构造器来添加更复杂的查询条件比如根据用户名模糊查询等 // 以下是示例如果name不为空进行模糊查询实际根据需求调整 if (name! null !name.isEmpty()) { // 假设User实体类中有对应的username字段用于查询此处只是示例需根据实际调整 LambdaQueryWrapper queryWrapper new LambdaQueryWrapper(); queryWrapper.like(User::getName, name); return baseMapper.selectPage(page, queryWrapper); } // 如果没有额外条件直接进行简单分页查询 return baseMapper.selectPage(page, null); } Override public User findByLoginName(String loginName) { return userMapper.findByLoginName(loginName); } Override public Result add(User user) { // 登录名校验 if (user.getLoginName() null || “”.equals(user.getLoginName())) { return Result.error(“登录名不能为空”); } // 登录名重复校验 if (findByLoginName(user.getLoginName()) ! null) { return Result.error(“登录名已存在请重新输入”); } if (user.getName() null || “”.equals(user.getName())) { return Result.error(“姓名不能为空”); } if (user.getPassword() null || “”.equals(user.getPassword())) { user.setPassword(Md5Util.getMD5String(“123456”)); }else{ user.setPassword(Md5Util.getMD5String(user.getPassword())); } if (userMapper.insert(user) 0) { return Result.success(“添加成功”); } return Result.error(“添加失败”); } } UserMapper.java中 package com.example.demo.mapper; import com.example.demo.entity.User; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; /* ** 用户信息表 Mapper 接口 ** * author HuaXiang * since 2024-12-06/ Mapper public interface UserMapper extends BaseMapper { Select(“SELECT * FROM user WHERE login_name #{loginName}”) User findByLoginName(String loginName); } 使用swagger测试新增用户功能在浏览器中输入http://localhost:9999/doc.html请求参数如下 { “loginName”: “user1”, “password”: “user1”, “name”: “user1”, “sex”: “男”, “phone”: “15612341234” }数据库中查看已经成功插入用户user1密码也为user1#### 1.13.2 用户登录1. 接口定义POST请求路径为/login,2. 参数校验对User对象判断判断对象或则和loginNamepassword是否为空为空则直接返回错误信息3. 用户名存在性校验调用userService.findByLoginName方法4. 密码正确性校验及登陆成功处理。 /* * 用户登录 * param user * return/ PostMapping(“/login”) Operation(summary “用户登录”) Parameters({ Parameter(name “loginName”, description “登录名”, required true, schema Schema(type “sting”)), Parameter(name “password”, description “密码”, required true, schema Schema(type “sting”)) }) public Result login(RequestBody User user) { if (user null || “”.equals(user.getLoginName()) || user.getLoginName() null || “”.equals(user.getPassword()) || user.getPassword() null) { return Result.error(“用户名密码不能为空”); } // 检验用户名是否存在 User eruser userService.findByLoginName(user.getLoginName()); if (eruser null) { return Result.error(“用户名不存在”); } // 检验用户密码是否正确 if (Md5Util.getMD5String(user.getPassword()).equals(eruser.getPassword())) { MapString, Object claims new HashMap(); claims.put(“id”, eruser.getId()); claims.put(“name”, eruser.getName()); claims.put(“loginName”, eruser.getLoginName()); String token JwtUtil.getToken(claims); return Result.success(token); } return Result.error(“密码错误”); } 测试用刚刚新创建的用户测试用户登录功能。#### 1.13.3 获取当前用户信息UserController.java /* * 获取当前登录用户信息 * return User/ GetMapping(“/currentUser”) Operation(summary “获取当前登录用户信息”) Parameter(name “Authorization”, in ParameterIn.HEADER, required true, description “token”) public Result getCurrentUser() { MapString, Object userSession ThreadLocalUtil.get(); int id (int) userSession.get(“id”); User user userService.getUserById(id); if (user ! null) { return Result.success(user); } return Result.error(“用户状态异常”); } UserService.java User getUserById(int id); UserServiceImpl.java Override public User getUserById(int id) { return userMapper.getUserById(id); } UserMapper.java Select(“SELECT * FROM user WHERE id #{id}”) User getUserById(int id); 测试复制1.13.2中用户登录成功返回的token值作为请求头#### 1.13.4 查询所有用户信息UserController.javas /* * 查询所有用户信息 * return List/ GetMapping(“/userList”) Operation(summary “查询所有用户信息”) Parameter(name “Authorization”, in ParameterIn.HEADER, required true, description “token”) public ResultList userList() { List userList userService.getUserList(); if (userList null) { return Result.error(“查询失败”); } return Result.success(userList); } UserService.java List getUserList(); UserServiceImpl.java /* * 查询所有用户信息 * return List/ Override public List getUserList() { return userMapper.selectList(null); } ### 1.14 删除和修改用户信息#### 1.14.1 删除用户信息UserController.java /* * 删除用户 */ DeleteMapping(“/delete/{id}”) Operation(summary “删除用户信息”) Parameters({ Parameter(name “Authorization”, in ParameterIn.HEADER, required true, description “token”), Parameter(name “id”, required true, description “用户id”) }) public Result delete(PathVariable int id) { boolean result userService.deleteById(id); // 调用service层的方法根据loginname删除用户信息这里假设UserService中有removeById方法 if (result) { return Result.success(“用户删除成功”); } else { return Result.error(“用户删除失败”); } } UserService.java boolean deleteById(int id); UserServiceImpl.java Override public boolean deleteById(int id) { return userMapper.deleteById(id) 0; } 测试#### 1.14.2 修改用户信息UserController.java PutMapping(“/update”) Operation(summary “修改用户信息”) Parameter(name “Authorization”, in ParameterIn.HEADER, required true, description “token”) public Result updateUser(RequestBody User user) { MapString, Object userSession ThreadLocalUtil.get(); int id (int) userSession.get(“id”); user.setId(id); user.setPassword(Md5Util.getMD5String(user.getPassword())); if (userService.update(user) 0) { return Result.success(“修改成功”); }else { return Result.error(“修改失败”); } } UserService.java int update(User user); UserServiceImpl.java Override public int update(User user) { return userMapper.updateById(user); } 测试先在请求头部中加上Authorization。1.13.2中用户登录的返回的data请求参数如下将性别修改为女 { “loginName”: “user1”, “password”: “user1”, “name”: “user1”, “sex”: “女”, “phone”: “15612341234” }