摘要:项目源码:https://gitee.com/zero-one-zsj/forum 1.数据库设计1.1 用户表t_user字段 类型 非空 (Y/N) 主键 (Y/N) 默认值 备注 id bigint Y Y 编号,主键自增 username
项目源码:https://gitee.com/zero-one-zsj/forum
1.数据库设计1.1 用户表t_user字段
类型
非空 (Y/N)
主键 (Y/N)
默认值
备注
id
bigint
Y
Y
编号,主键自增
username
varchar(20)
Y
N
用户名,唯一
password
varchar(32)
Y
N
加密后的密码
nickname
varchar(50)
Y
N
昵称
phoneNum
varchar(20)
N
N
手机号
varchar(50)
N
N
电子邮箱
gender
tinyint
Y
N
2
性别 0 女,1 男,2 保密
salt
varchar(32)
Y
N
为密码加盐
avatarUrl
varchar(255)
N
N
用户头像路径
articleCount
int
Y
N
0
发帖数量
isAdmin
tinyint
Y
N
0
是否管理员 0 否,1 是
remark
varchar(1000)
N
N
备注,自我介绍
state
tinyint
Y
N
0
状态 0 正常,1 禁言
deleteState
tinyint
Y
N
0
是否删除,0 否,1 是
createTime
dateTime
Y
N
创建时间,精确到秒
updateTime
dateTime
Y
N
更新时间,精确到秒
代码语言:javascript复制DROP DATABASE IF EXISTS forum_db;
#创建数据库并指定字符集
CREATE DATABASE forum_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE forum_db;
#创建用户表
DROP TABLE IF EXISTS t_user;
CREATE TABLE t_user(
id BIGINT PRIMARY KEY auto_increment COMMENT '编号,主键自增',
username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名,唯一',
`password` VARCHAR(32) NOT NULL COMMENT '加密后的密码',
nickname VARCHAR(50) NOT NULL COMMENT '昵称',
phoneNum VARCHAR(20) COMMENT '手机号',
email VARCHAR(50) COMMENT '电子邮箱',
gender TINYINT NOT NULL DEFAULT 2 COMMENT '性别 0女,1男,2保密',
salt VARCHAR(32) NOT NULL COMMENT '为密码加盐',
avatarUrl VARCHAR(255) COMMENT '用户头像路径',
avatarCount INT NOT NULL DEFAULT 0 COMMENT '发帖数量',
isAdmin TINYINT NOT NULL DEFAULT 0 COMMENT '是否是管理员 0否,1是',
remark VARCHAR(100) COMMENT '备注,自我介绍',
state TINYINT NOT NULL DEFAULT 0 COMMENT '状态 0正常,1禁言',
deleteState TINYINT NOT NULL DEFAULT 0 COMMENT '是否删除,0否,1是',
createTime DATETIME NOT NULL COMMENT '创建时间,精确到秒',
updateTime DATETIME NOT NULL COMMENT '更新时间,精确到秒'
);1.2 版块表t_board代码语言:javascript复制-- ----------------------------
-- 创建版块表 t_board
-- ----------------------------
DROP TABLE IF EXISTS `t_board`;
CREATE TABLE `t_board` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '版块编号,主键,⾃增',
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '版块名,⾮空',
`articleCount` int(11) NOT NULL DEFAULT 0 COMMENT '帖⼦数量,默认0',
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序优先级,升序,默认0,',
`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态,0 正常,1禁⽤,默认0',
`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0否,1是,默认0',
`createTime` datetime NOT NULL COMMENT '创建时间,精确到秒,⾮空',
`updateTime` datetime NOT NULL COMMENT '更新时间,精确到秒,⾮空',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci COMMENT = '版块表' ROW_FORMAT = Dynamic;1.3 帖子表t_article代码语言:javascript复制DROP TABLE IF EXISTS `t_article`;
CREATE TABLE `t_article` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '帖⼦编号,主键,⾃增',
`boardId` bigint(20) NOT NULL COMMENT '关联板块编号,⾮空',
`userId` bigint(20) NOT NULL COMMENT '发帖⼈,⾮空,关联⽤⼾编号',
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT
NULL COMMENT '标题,非空,最⼤⻓度100个字符',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
COMMENT '帖⼦正⽂,⾮空',
`visitCount` int(11) NOT NULL DEFAULT 0 COMMENT '访问量,默认0',
`replyCount` int(11) NOT NULL DEFAULT 0 COMMENT '回复数据,默认0',
`likeCount` int(11) NOT NULL DEFAULT 0 COMMENT '点赞数,默认0',
`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态 0正常 1 禁⽤,默认0',
`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0 否 1 是,默认0',
`createTime` datetime NOT NULL COMMENT '创建时间,精确到秒,⾮空',
`updateTime` datetime NOT NULL COMMENT '修改时间,精确到秒,⾮空',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci COMMENT = '帖⼦表' ROW_FORMAT = Dynamic;1.4 帖子回复表t_article_reply代码语言:javascript复制-- ----------------------------
-- 创建帖⼦回复表 t_article_reply
-- ----------------------------
DROP TABLE IF EXISTS `t_article_reply`;
CREATE TABLE `t_article_reply` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号,主键,⾃增',
`articleId` bigint(20) NOT NULL COMMENT '关联帖子编号,⾮空',
`postUserId` bigint(20) NOT NULL COMMENT '楼主⽤⼾,关联⽤⼾编号,⾮空',
`replyId` bigint(20) NULL DEFAULT NULL COMMENT '关联回复编号,⽀持楼中楼',
`replyUserId` bigint(20) NULL DEFAULT NULL COMMENT '楼主下的回复⽤⼾编号,支持楼中楼',
`content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '回贴内容,⻓度500个字符,⾮空',
`likeCount` int(11) NOT NULL DEFAULT 0 COMMENT '点赞数,默认0',
`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态 0 正常,1禁⽤,默认0',
`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0否 1是,默认0',
`createTime` datetime NOT NULL COMMENT '创建时间,精确到秒,⾮空',
`updateTime` datetime NOT NULL COMMENT '更新时间,精确到秒,⾮空',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci COMMENT = '帖⼦回复表' ROW_FORMAT = Dynamic;1.5 站内信表t_message代码语言:javascript复制-- ----------------------------
-- 创建站内信表 for t_message
-- ----------------------------
DROP TABLE IF EXISTS `t_message`;
CREATE TABLE `t_message` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '站内信编号,主键,⾃增',
`postUserId` bigint(20) NOT NULL COMMENT '发送者,并联⽤⼾编号',
`receiveUserId` bigint(20) NOT NULL COMMENT '接收者,并联⽤⼾编号',
`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT
NULL COMMENT '内容,⾮空,⻓度255个字符',
`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态 0未读 1已读,默认0',
`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0否,1是,默认0',
`createTime` datetime NOT NULL COMMENT '创建时间,精确到秒,⾮空',
`updateTime` datetime NOT NULL COMMENT '更新时间,精确到秒,⾮空',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci COMMENT = '站内信表' ROW_FORMAT = Dynamic;1.6 创建用户表代码语言:javascript复制DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '⽤⼾编号,主键,⾃增',
`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT
NULL COMMENT '⽤⼾名,⾮空,唯⼀',
`password` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT
NULL COMMENT '加密后的密码',
`nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT
NULL COMMENT '昵称,⾮空',
`phoneNum` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL
DEFAULT NULL COMMENT '⼿机号',
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL
DEFAULT NULL COMMENT '邮箱地址',
`gender` tinyint(4) NOT NULL DEFAULT 2 COMMENT '0⼥ 1男 2保密,⾮空,默认2',
`salt` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
COMMENT '为密码加盐,⾮空',
`avatarUrl` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
NULL DEFAULT NULL COMMENT '⽤⼾头像URL,默认系统图⽚',
`articleCount` int(11) NOT NULL DEFAULT 0 COMMENT '发帖数量,⾮空,默认0',
`isAdmin` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否管理员,0否 1是,默认0',
`remark` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL
DEFAULT NULL COMMENT '备注,⾃我介绍',
`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态 0 正常,1 禁⾔,默认0',
`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除 0否 1是,默认0',
`createTime` datetime NOT NULL COMMENT '创建时间,精确到秒',
`updateTime` datetime NOT NULL COMMENT '更新时间,精确到秒',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `user_username_uindex`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci COMMENT = '⽤⼾表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;.配置数据源2.1 pom.xml中引用依赖统一管理版本,在properties标签中加入版本号
代码语言:javascript复制
springfox-boot-starter 是 Spring 生态中用于集成 Swagger 的工具
添加依赖,在dependencies标签中加入相关依赖
代码语言:javascript复制
2.2 application.yml中添加配置在spring节点下添加数据源配置项
代码语言:javascript复制spring:
application:
name: 论坛系统
# 配置数据源
datasource:
url: jdbc:mysql://127.0.0.1:3306/forum_db?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: jqka
driver-class-name: com.mysql.cj.jdbc.Driver
server:
port: 58080 #自定义服务器端口
logging:
pattern:
dateformat: MM-dd HH:mm:ss #日期显示格式
level:
root: info #日志默认级别
com.example.forum: debug #指定包下的日志级别
file:
path: D:/JavaCode/log2.3 生成类与映射文件2.3.1 pom.xml中引用依赖统一管理版本,在properties标签中加入版本号
代码语言:javascript复制
代码语言:javascript复制
src/main/resources/mybatis/generatorConfig.xml
2.3.2 创建generatorConfig.xml驱动包:mysql-connector-java-5.1.49.jar
代码语言:javascript复制
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
connectionURL="jdbc:mysql://127.0.0.1:3306/forum_db?characterEncoding=utf8&useSSL=false" userId="root" password="jqka">
2.3.3 运行插件生成文件 在src/main/resources下创建mapper目录
点下下图重新加载Maven项目,在Plugins节点下出现mybatis-generator,双击运行,在对应的目录下生成相应的类与映射文件,如下图所示:
2.3.4 在Insert标签中添加获取主键值的选项代码语言:javascript复制
useGeneratedKeys="true" keyProperty="id" > useGeneratedKeys="true":开启 “自动获取数据库生成的主键” 功能(适用于数据库主键自增的场景,如 MySQL 的 AUTO_INCREMENT)。 keyProperty="id":指定将数据库生成的主键值,回填到 User 实体类的 id 属性中(插入后可直接通过 user.getId() 获取自动生成的主键)。 2.3.5 添加mapper注解dao包下的每个xxxMapper.java加入@Mapper注解(不加也行) 2.3.6 扫描配置 config包下新建MybatisConfig类,指定Mybatis的扫路径 配置 Mapper 扫描路径(如通过 @MapperScan("com.example.forum.dao"))的核心作用是:告诉框架 “去哪里找数据访问接口(Mapper)”,并自动为这些接口创建实现类 核心功能 自动注册 Mapper 接口:通过 @MapperScan 指定路径后,MyBatis 会自动识别该包下的接口为数据访问层(DAO)组件,省去了在每个 Mapper 接口上单独添加 @Mapper 注解的麻烦。 整合 Spring 与 MyBatis:该配置类配合 MyBatis 的 Starter 依赖(如 mybatis-spring-boot-starter),实现两者的无缝集成,使得 Mapper 接口可以通过 @Autowired 直接注入到 Service 层使用。 代码语言:javascript复制package com.example.forum.config; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration; /** * 配置mybatis的扫描路径 */ @Configuration @MapperScan("com.example.forum.dao") public class MyBatisConfig { }application.yml中加入mybatis配置 代码语言:javascript复制# mybatis 相关配置,单独配置,顶格写 mybatis: mapper-locations: classpath:mapper/**/*.xml # 指定 xxxMapper.xml的扫描路径3.通过Git推送至远程仓库代码语言:javascript复制# 查看当前状态,列出未修改后添加的文件 git status # 添加修改后的文件到暂存区,再次运行git status,上⾯的文件会变为绿色显示 git add . # 提交到本地仓库 git commit -m '第⼀次提交' # 推送到远程仓库 git push4.编写公共代码4.1 定义状态码对执行业务处理逻辑过程中可能出现的成功与失败状态做针对性描述,用枚举定义状态码,先定义一部分,业务中遇到新的问题再添加 代码语言:javascript复制package com.example.forum.common; public enum ResultCode { /** 定义状态码 */ SUCCESS (0, "成功"), FAILED (1000, "操作失败"), FAILED_UNAUTHORIZED (1001, "未授权"), FAILED_PARAMS_VALIDATE (1002, "参数校验失败"), FAILED_FORBIDDEN (1003, "禁⽌访问"), FAILED_CREATE (1004, "新增失败"), FAILED_NOT_EXISTS (1005, "资源不存在"), AILED_USER_EXISTS (1101, "用户已存在"), FAILED_USER_NOT_EXISTS (1102, "用户不存在"), FAILED_LOGIN (1103, "用户名或密码错误"), FAILED_USER_BANNED (1104, "您已被禁言, 请联系管理员, 并重新登录."), FAILED_TWO_PWD_NOT_SAME (1105, "两次输的密码不⼀致"), ERROR_SERVICES (2000, "服务器内部错误"), ERROR_IS_NULL (2001, "IS NULL."); //状态码 int code; //描述信息 String message; ResultCode(int code, String message) { this.code = code; this.message = message; } //使用@Getter也可以 public int getCode() { return code; } public String getMessage() { return message; } @Override public String toString() { return "code = " + code + ", message = " + message + ". "; } }4.2 定义返回结果系统实现前后端分离,统一返回JSON格式的字符串,需要定义一个类,其中包含状态码,描述信息,返回的结果数据 方法签名 作用(什么时候用) 举个实际例子(接口返回) static AppResult success() 无数据、无自定义消息:只需要告诉前端 “操作成功”(比如删除数据、修改状态成功) 前端调用 “删除用户” 接口,返回:{"code":200, "message":"操作成功", "data":null} static AppResult success(String message) 无数据、但要自定义提示(比如 “注销账号成功”,而非默认的 “操作成功”) 前端调用 “注销账号” 接口,返回:{"code":200, "message":"注销账号成功", "data":null} 有数据、用默认消息:需要返回业务数据(比如查询列表、查询详情) 前端调用 “查询用户列表” 接口,返回:{"code":200, "message":"操作成功", "data":[{id:1,name:"张三"}]} static 有数据、且自定义提示:既要返回数据,又要个性化提示(比如 “查询我的订单成功”) 前端调用 “查询我的订单” 接口,返回:{"code":200, "message":"查询我的订单成功", "data":[{orderId:1,price:100}]} 方法签名 作用(什么时候用) 举个实际例子(接口返回) static AppResult failed() 无自定义消息:通用失败(比如服务器未知错误,用默认的 “操作失败”) 前端调用 “提交订单” 时数据库报错,返回:{"code":500, "message":"操作失败", "data":null} static AppResult failed(String message) 自定义失败提示:需要告诉前端具体失败原因(比如 “手机号已被注册”) 前端调用 “注册” 时手机号重复,返回:{"code":500, "message":"手机号已被注册", "data":null} static AppResult failed(ResultCode resultCode) 用枚举定义的失败场景:统一管理特定失败(比如参数错误、无权限,避免硬编码状态码) 前端调用 “查询用户” 时传错参数,返回:{"code":400, "message":"参数错误", "data":null}(对应 ResultCode.PARAM_ERROR) 4.3 自定义异常ApplicationException 是 项目自定义的 “业务异常类”,专门用于处理 业务逻辑层面的错误(比如 “手机号已注册”“余额不足”“无权限操作” 等),区别于 Java 自带的 “系统异常”(如 NullPointerException 空指针、ArrayIndexOutOfBoundsException 数组越界)。它的核心作用是 “将业务失败信息标准化封装,方便全局统一处理,最终给前端返回一致的错误响应”。 ApplicationException 是业务错误的 “标准化载体”: 它把 “业务失败的状态码、提示、详情” 打包,让错误信息更完整; 它区分了 “业务错” 和 “系统错”,让全局处理更精准; 它配合全局异常处理器,最终实现 “前后端错误响应格式统一”,减少沟通和开发成本。 4.4 全局异常处理使用@ControllerAdvice+@ExceptionHandler注解实现统一异常处理 拦截范围: @ControllerAdvice 会拦截所有标注了 @Controller 或 @RestController 的类中未被手动 try-catch 的异常(即业务代码中向外抛出的异常)。 处理逻辑: 结合 @ExceptionHandler(异常类型.class),可以按异常类型分流处理: 自定义业务异常(如 ApplicationException):返回提前定义的错误信息(如 “用户名已存在”); 系统异常(如 NullPointerException):返回兜底提示(如 “服务异常,请稍后再试”)。 解决的核心问题: 全局化、标准化、解耦化 避免重复 try-catch 响应格式统一 日志与排查更高效 代码语言:javascript复制@Slf4j @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ApplicationException.class) @ResponseBody public AppResult applicationExceptionHandler(ApplicationException e) { e.printStackTrace(); log.error(e.getMessage()); //优先返回异常中携带的标准化错误结果(ErrorResult) if (e.getErrorResult() != null) { // 返回异常类中记录的状态 return e.getErrorResult(); } //非空校验 //若异常无携带结果,校验异常消息是否为空 if (e.getMessage() == null || "".equals(e.getMessage())) { //返回默认服务错误 return AppResult.failed(ResultCode.ERROR_SERVICES); } // 返回具体异常信息 return AppResult.failed(e.getMessage()); } @ExceptionHandler(Exception.class) @ResponseBody public AppResult exceptionHandler(Exception e) { //打印异常信息 e.printStackTrace(); //打印日志 log.error(e.getMessage()); //非空判断 if (e.getMessage() == null || "".equals(e.getMessage())) { return AppResult.failed(ResultCode.ERROR_SERVICES); } //返回异常信息 return AppResult.failed(e.getMessage()); } }4.5 测试异常处理代码语言:javascript复制@GetMapping("/exception") public String exception() throws Exception { throw new Exception("抛出exception异常..."); } @GetMapping("/application") public String application() { throw new ApplicationException("抛出applicationException异常..."); }4.6 登录拦截器4.6.1 拦截路径拦截路径是指我们定义的这个拦截器,对哪些请求生效 我们在注册配置拦截器的时候,通过addPathPatterns()方法指定要拦截哪些请求.也可以通过excludePathPatterns()指定不拦截哪些请求. 上述代码中,我们配置的是/**,表示拦截所有的请求。 比如用户登录校验,我们希望可以对除了登录之外所有的路径生效。 代码语言:javascript复制@Configuration public class AppInterceptorConfigurer implements WebMvcConfigurer { //注入自定义的登录拦截器 @Resource private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加登录拦截器 registry.addInterceptor(loginInterceptor) // 添加⽤⼾登录拦截器 .addPathPatterns("/**") // 拦截所有请求 .excludePathPatterns("/sign-in.html") // 排除登录HTML .excludePathPatterns("/sign-up.html") // 排除注册HTML .excludePathPatterns("/user/login") // 排除登录api接⼝ .excludePathPatterns("/user/register") // 排除注册api接⼝ .excludePathPatterns("/user/logout") // 排除退出api接⼝ .excludePathPatterns("/swagger*/**") // 排除登录swagger下所有 .excludePathPatterns("/v3*/**") // 排除登录v3下所有,与 swagger相关 .excludePathPatterns("/dist/**") // 排除所有静态⽂件 .excludePathPatterns("/image/**") .excludePathPatterns("/**.ico") .excludePathPatterns("/js/**"); } }4.6.2 拦截器执行流程 添加拦截器后,执行Controller的方法之前,请求会先被拦截器拦截住.执行preHandle方法, 这个方法需要返回一个布尔类型的值,如果返回true,就表示放行本次操作,继续访问controller中的方法. 如果返回false,则不会放行(controller中的方法也不会执行). controller当中的方法执行完毕后,再回过来执行postHandle()这个方法以及afterCompletion()方法,执行完毕之后,最终给浏览器响应数据. 代码语言:javascript复制@Component public class LoginInterceptor implements HandlerInterceptor { @Value(("${404Lounge.login.url}")) private String defaultURL; /** * * 前置处理(对请求的预处理) * @return true: 继续流程 false:流程终止 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取session对象 HttpSession session = request.getSession(); //判断session是否有效 if(session != null && session.getAttribute(AppConfig.USER_SESSION) != null){ return true; } //校验URL是否正确 if(!defaultURL.startsWith("/")) { defaultURL = "/" + defaultURL; } //强制将未登录用户的请求重定向到登录页面 response.sendRedirect(defaultURL); //中断流程 return false; } }4.7 实现API自动生成Swagger简介:Swagger是一套API定义的规范,按照这套规范的要求去定义接口及接口相关信息, 再通过可以解析这套规范工具,就可以生成各种格式的接口文档,以及在线接口调试页面,通过自动 文档的方式,解决了接口文档更新不及时的问题。 Springfox简介:是对Swagger规范解析并生成文档的一个实现。 Springfox文档:http://springfox.github.io/springfox/docs/snapshot/ 4.7.1 pom.xml中引用依赖统一管理版本,在properties标签中加入版本号 代码语言:javascript复制 代码语言:javascript复制 4.7.2 编写配置类代码语言:javascript复制package com.example.forum.config; import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.web.*; import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Swagger配置类 * */ // 配置类 @Configuration // 开启Springfox-Swagger @EnableOpenApi public class SwaggerConfig {/** * Springfox-Swagger基本配置 * @return */ @Bean public Docket createApi() { Docket docket = new Docket(DocumentationType.OAS_30) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.example.forum.controller")) .paths(PathSelectors.any()) .build(); return docket; } // 配置API基本信息 private ApiInfo apiInfo() { ApiInfo apiInfo = new ApiInfoBuilder() .title("404客厅API") .description("404客厅系统前后端分离API测试") .contact(new Contact("404Lounge", "http://62.234.142.221:58080/sign-in.html", "435752097@qq.com")) .version("1.0") .build(); return apiInfo; } /** * 解决SpringBoot 6.0以上与Swagger 3.0.0 不兼容的问题 * 复制即可 **/ @Bean public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) { List Collection webEndpointsSupplier.getEndpoints(); allEndpoints.addAll(webEndpoints); allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); String basePath = webEndpointProperties.getBasePath(); EndpointMapping endpointMapping = new EndpointMapping(basePath); boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath); return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null); } private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) { return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT)); } }4.7.3 application.yml中添加配置在spring节点下添加mvc配置项 由于SpringBoot2.6之后版本把SpringMVC路径匹配策略修改为 MatchingStrategy.PATH_PATTERN_PARSER; 而Springfox-Swagger还没有更新版本,我们暂时先把路径匹配策略回退到之前的 MatchingStrategy.ANT_PATH_MATCHER 代码语言:javascript复制mvc: pathmatch: matching-strategy: ANT_PATH_MATCHER #Springfox-Swagger兼容性配置4.7.4 API常见注解4.7.5 修改测试接口代码语言:javascript复制@Api(tags = "测试类相关接口") @RestController @RequestMapping("/test") public class TestController { @ApiOperation("测试接口1,你好Spring boot") @GetMapping("/hello") public String hello() { return "hello"; } @ApiOperation("测试接口4,按传入的姓名传入你好信息") @PostMapping("/helloByName") public AppResult helloByName(@ApiParam("姓名") @RequestParam("name") String name) { return AppResult.success("hello " + name); } @ApiOperation("测试接口2,显示抛出异常信息") @GetMapping("/exception") public String exception() throws Exception { throw new Exception("抛出exception异常..."); } @ApiOperation("测试接口3,显示自定义异常信息") @GetMapping("/application") public String application() { throw new ApplicationException("抛出applicationException异常..."); } }4.7.6 访问API列表4.8 创建工具类4.8.1 创建MD5加密工具类项目中使用commons-codec,它是Apache提供的用于摘要运算、编码解码的工具包。常见的编码解码工具Base64、MD5、HeX、SHA1、DES等。 pom.xml中导入依赖,SpringBoot已经对这个包做了版本管理,所以这里不用指定版本号 代码语言:javascript复制 密码加密流程: 定义一个原始密码 生成盐值(拢动字符) 原密码进行MD5加密 = 密文1 密文1 + 盐值 = 密文2 对密文2进行MD5加密 代码语言:javascript复制public class MD5Util { //传入原字符串后可以得到一个经过md5加密的密文 /** * 对字符串进行明文加密 * @param str 明文 * @return 返回密文 */ public static String md5(String str) { return DigestUtils.md5Hex(str); } /** * 对用户密码进行加密 * 原始字符串加密后与扰动字符串组合再进⾏⼀次MD5加密 * @param str 密码明文 * @param salt 扰动字符 盐值 * @return 返回密文 */ public static String md5Salt(String str, String salt) { return md5(md5(str) + salt); } }代码语言:javascript复制String salt = UUIDUtil.UUID_32(); String ciphertext = MD5Util.md5Salt(password, salt);4.8.2 创建UUID工具类UUID(Universally Unique Identifier)是一种 “全球唯一” 的字符串标识(基于时间戳、机器 MAC 地址、随机数等信息生成),几乎不会出现重复。 代码语言:javascript复制package com.example.forum.utils; import java.util.UUID; public class UUIDUtil { /** * 标准的UUID * @return */ public static String UUID_36() { return UUID.randomUUID().toString(); } /** * 生成一个32位的 UUID 去掉 4 个 - * @return */ public static String UUID_32() { return UUID.randomUUID().toString().replace("-", ""); } }5.1 注册(创建普通用户)5.1.1 参数要求参数名 描述 类型 默认值 条件 username 用户名 String 必须 nickname 昵称 String 与用户名相同 必须 password 密码 String 必须 passwordRepeat 确认密码 String 必须,与密码相同 5.1.2 接口规范代码语言:javascript复制// 请求 POST /user/register HTTP/1.1 Content-Type: application/x-www-form-urlencoded username=user222&nickname=user222&password=123456&passwordRepeat=123456 // 响应 HTTP/1.1 200 Content-Type: application/json {"code":0,"message":"成功","data":null}5.1.4 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 设置默认值 必传参数以外的一些参数要设置默认值 单元测试 密码的密文:对(原始密码+盐值)进行md5加密 Controller实现方法并对外提供API接口 测试API接口 实现前端逻辑,完成前后端交互 5.1.5 API注解和校验注解添加API注解和校验注解 @ApiOperation:生成API时描述方法 @ApiParam:生成API时描述单个参数 @RequestParam:请求时指定参数名 @NonNull:请求时参数不能为空 5.2 登录5.2.1 参数要求 注册时需要用户提交的参数列表 参数名 描述 类型 默认值 条件 username 用户名 String 必须 password 密码 String 必须 5.2.2 接口规范代码语言:javascript复制// 请求 POST /user/login HTTP/1.1 Content-Type: application/x-www-form-urlencoded username=bitboy&password=123456 // 响应 HTTP/1.1 200 Content-Type: application/json {"code":0,"message":"成功","data":null}5.2.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 1,2自动生成了 定义Service接 根据用户名在数据库中查询用户信息 对密码进行登录校验 实现Service接口 单元测试 Controller实现方法并对外提供API接口 测试API接口 实现前端逻辑,完成前后端交互 设置session的意义: 表示用户已登陆状态 HTTP协议是无状态的(服务器默认是不记得上一次的请求时谁发的),当用户登录成功后,将登陆的User对象存入session,打个标记标识已经登陆了,后续访问当前登录用户下的其他接口时,通过session中是否存在该对象来判断用户是否已登录 方便后续操作获取用户信息 从session中获取之前存入的User对象 实现会话级别的数据共享 session是用户级别的存储空间(每个用户的session都是独立的),登陆后当前用户会话下的所有操作都能共享session中的User数据 5.3 获取用户信息(根据id查询)5.3.1 参数要求参数名 描述 类型 默认值 条件 id 用户 Id long 可以为空 5.3.2 接口规范代码语言:javascript复制// 请求 GET /user/info HTTP/1.1 GET /user/info?id=1 HTTP/1.1 // 响应 HTTP/1.1 200 Content-type: application/json //具体的User对象 { "code": 0, "message": "成功", "data": { "id": 25, "username": "user223", "nickname": "user223", "phoneNum": null, "email": null, "gender": 1, "avatarUrl": null, "articleCount": 0, "isAdmin": 0, "state": 0, "createTime": "2025-09-08 15:06:10", "updateTime": "2025-09-08 15:06:10" } }5.3.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 测试API接口 实现前端逻辑,完成前后端交互 修复返回值存在的缺陷 通过观察登录成功的返回结果发现,用户信息中的password,salt,deletState不应该返回给前台,在User类中的对应属性上加@Jsonlgnore注解,可以使对应的字段不参与JSON的序列化修改日期格式为yyyy-MM-dd HH:mm:ss,在application.yml中添加配置 代码语言:javascript复制jackson: date-format: yyyy-MM-dd HH:mm:ss # 日期格式 default-property-inclusion: NON_NULL # 不为null时序列化5.4 退出登录5.4.1 参数要求无参数要求 实现逻辑 用户访问退出接口 服务器注销Session 返回成功或失败 如果返回成功浏览器跳转到相应页面 结束 退出后跳转到前端登陆界面 5.4.2 接口规范代码语言:javascript复制// 请求 GET http://127.0.0.1:58080/user/logout HTTP/1.1 // 响应 HTTP/1.1 200 Content-Type: application/json {"code":0,"message":"成功","data":null}5.4.3 实现流程在Contrller中实现销毁Session就完成了用户退出功能,不需要编写Service层代码 5.5 登录拦截器LoginInterceptor,重写preHandle方法 true: 继续流程 false:流程终止 判断session是否有效 没有登陆强制跳转到登陆界面 修改application.yml配置文件,添加跳转页面 代码语言:javascript复制CodeOnHub: login: url: sign-in.html # 未登录状况下强制跳转页面AppInterceptorConfigurer 拦截路径 5.6 获取首页板块列表在首页显示的版块信息,可以通过以下两种方式解决 方法一:单独提供查询前N条记录的接口,用来控制首页中版块的个数 方法二:通过配置表中state字段来实现,提供查询所有版块的接口 两种方式任选一个都可以,项目中使用方法一 5.6.1 参数要求无参数要求 实现逻辑: 用户访问首页 服务器查询有效的版块并按排序字段排序 返回版块集合 5.6.2 接口规范代码语言:javascript复制请求 URL:http://127.0.0.1:58080/board/topList 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": [ { "id": 1, "name": "Java", "articleCount": 5, "sort": 1, "state": 0, "createTime": "2023-01-14 11:02:18", "updateTime": "2023-01-14 11:02:18" }, { "id": 2, "name": "C++", "articleCount": 1, "sort": 2, "state": 0, "createTime": "2023-01-14 11:02:41", "updateTime": "2023-01-14 11:02:41" } ] }5.6.3 实现流程在Mapper.xml中编写SQL语句 BoardExtMapper.xml 代码语言:javascript复制SELECT * FROM t_board WHERE state = 0 AND deleteState = 0 ORDER BY sort ASC LIMIT 0,9代码语言:javascript复制# 项目自定义相关配置 CodeOnHub: login: url: sign-in.html # 未登录状况下强制跳转页面 index: # 首页配置节点 board-num: 9 # 首页中显示的版块个数在Mapper.java中定义方法 代码语言:javascript复制List 实现Service接口 单元测试 Controller实现方法并对外提供API接口 测试API接口 实现前端逻辑,完成前后端交互 5.7 获取指定板块信息5.7.1 参数要求参数名 描述 类型 默认值 条件 id 版块 Id long 必须 5.7.2 接口规范代码语言:javascript复制请求方式:GET 请求 URL:http://127.0.0.1:58080/board/getById 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": { "id": 1, "name": "Java", "articleCount": 5, "sort": 1, "state": 0, "createTime": "2025-01-14 11:02:18", "updateTime": "2025-01-14 11:02:18" } }5.7.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 1,2自动生成了 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 测试API接口 实现前端逻辑,完成前后端交互 5.8 发布新帖5.7.1 参数要求参数名 描述 类型 默认值 条件 boardId 版块 Id long 必须 title 文章标题 String 必须 content 帖子内容 String 必须 5.7.2 接口规范代码语言:javascript复制// 请求 POST http://127.0.0.1:58080/article/create HTTP/1.1 Content-Type: application/x-www-form-urlencoded boardId=1&title=% E6% B5%8B% E8% AF%95% E6%96% B0% E5% B8%96% E5% AD%90% E6% A0%87% E9% A2%98&content=% E6% B5%8B% E8% AF%95% E6%96% B0% E5% B8%96% E5% AD%90% E5%86%85% E5% AE% B9 // 响应 HTTP/1.1 200 Content-Type: application/json {"code":0,"message":"成功","data":null}5.7.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 校验信息将新帖内容写入到文章表t_board中 更新用户发帖数,更新用户表t_user中 更新板块帖子数板块表t_board中 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.9 获取帖子列表对应版块中显示的帖子列表以发布时间降序排列,不传入版块Id返回所有帖子 用户点击某个版块或首页时,将版块Id做为参数向服务器发送请求 服务器接收请求,并获取版块Id,查询对应版块下的所有帖子 返回查询结果5.8.1 参数要求参数名 描述 类型 默认值 条件 boardId 版块 Id Long 可为空 5.8.2 接口规范代码语言:javascript复制// 请求 // 返回指定版块下的帖子列表 GET http://127.0.0.1:58080/article/getAllByBoardId?boardId=1 HTTP/1.1 // 返回所有的帖子列表 GET http://127.0.0.1:58080/article/getAllByBoardId HTTP/1.1 // 响应 HTTP/1.1 200 Content-Type: application/json { "code": 0, "message": "成功", "data": [ { "id": 17, "boardId": 1, "userId": 1, "title": "测试删除", "visitCount": 8, "replyCount": 1, "likeCount": 1, "state": 0, "createTime": "2025-07-05 04:10:46", "updateTime": "2025-07-05 11:22:43", "board": { "id": 1, "name": "Java" }, "user": { "id": 1, "nickname": "bitboy", "phoneNum": null, "email": null, "gender": 1, "avatarUrl": null }, "own": false }5.8.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 ★5.8.4 MyBatis 映射文件参数含义多表关联查询 关联用户表(t_user)和文章表(t_article),主要是为了在查询帖子列表时,同时获取发布该帖子的用户信息 代码语言:javascript复制 columnPrefix="u_"/> columnPrefix="b_" /> select u.id as u_id, u.avatarUrl as u_avatarUrl, u.nickname as u_nickname, a.id, a.boardId, a.userId, a.title, a.visitCount, a.replyCount, a.likeCount, a.state, a.createTime, a.updateTime from t_article a, t_user u where a.userId = u.id and a.deleteState = 0 order by a.createTime DESC; select u.id as u_id, u.avatarUrl as u_avatarUrl, u.nickname as u_nickname, a.id, a.boardId, a.userId, a.title, a.visitCount, a.replyCount, a.likeCount, a.state, a.createTime, a.updateTime from t_article a, t_user u where a.userId = u.id and a.deleteState = 0 and a.boardId = #{boardId,jdbcType=BIGINT} order by a.createTime DESC; select u.id as u_id, u.avatarUrl as u_avatarUrl, u.nickname as u_nickname, u.gender as u_gender, u.isAdmin as u_isAdmin, u.state as u_state, u.deleteState as u_deleteState, b.id as b_id, b.name as b_name, b.state as b_state, b.deleteState as b_deleteState, a.id, a.boardId, a.userId, a.title, a.content, a.visitCount, a.replyCount, a.likeCount, a.state, a.createTime, a.updateTime from t_article a, t_user u, t_board b where a.userId = u.id and a.boardId = b.id and a.deleteState = 0 and a.id = #{id,jdbcType=BIGINT} 代码语言:javascript复制 作用:MyBatis 通过 namespace 关联接口与 XML,确保接口中的方法能找到对应的 SQL 语句。 代码语言:javascript复制 type="com.example.forum.model.Article" extends="ResultMapWithBLOBs"> id="AllInfoResultMap":当前结果集映射的唯一标识,供 type="com.example.forum.model.Article":指定该结果集映射对应的实体类(将查询结果封装为 Article 对象)。 extends="ResultMapWithBLOBs":继承另一个结果集映射(ResultMapWithBLOBs,通常包含文章内容等大字段的映射),避免重复定义公共字段。 子标签 代码语言:javascript复制 resultMap="com.example.forum.dao.UserMapper.BaseResultMap" columnPrefix="u_"/>property="user": 目标实体类中的属性名,指定 Article 类中存储用户信息的属性名。 resultMap="...":关联的用户结果集映射, 复用 UserMapper 中定义的 BaseResultMap(用户信息的字段映射规则)。 columnPrefix="u_":查询结果中用户相关字段的前缀(如 u_id、u_nickname),MyBatis 会自动去掉前缀并匹配 User 类的属性(如 u_id → id,u_nickname → nickname)。 代码语言:javascript复制 resultMap="com.example.forum.dao.BoardMapper.BaseResultMap" columnPrefix="b_"/>作用与用户关联类似,将查询结果中以 b_ 为前缀的字段(如 b_id、b_name)映射到 Article 类的 board 属性(private Board board;)。 关联用户的映射 将 u_ 前缀的字段通过 UserMapper 的 BaseResultMap 映射到 article的user 中进行多表关联查询,让数据库的关联数据与 Java 的对象关系自动对应 将带 u_ 前缀的用户字段映射到 Article 的 user 属性(即 User 对象)。 这种 MyBatis 结果集映射(尤其是通过 查询用户的帖子列表,这是两个表 5.10 根据帖子id获取详情5.10.1 参数要求参数名 描述 类型 默认值 条件 id 帖子 Id long 必须 5.10.2 接口规范代码语言:javascript复制请求方式:GET 请求 URL:http://127.0.0.1:58080/article/getById { "code": 0, "message": "成功", "data": { "id": 1, "boardId": 1, "userId": 1, "title": "单元测试", "visitCount": 14, "replyCount": 2, "likeCount": 3, "state": 0, "createTime": "2025-07-02 06:46:32", "updateTime": "2025-07-05 10:16:43", "content": "测试内容", "board": { "id": 1, "name": "Java" }, "user": { "id": 1, "nickname": "bitboy", "phoneNum": null, "email": null, "gender": 1, "avatarUrl": null }, "own": true } }5.10.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 非空校验 调用dao,获取帖子详情 更新帖子访问次数 获取要更新的帖子id 保存到数据库 更新返回对象的访问次数 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.11 修改帖子 当发帖人为当前用户时,显示编辑接钮,用户点击编辑接钮,进入编辑页面 获取帖子信息,并在对应的位置显示 用户修改帖子标题和内容 提交到服务器,服务器检验当前用户是否为发帖人,并更新数据库 返回更新结果 5.11.1 参数要求参数名 描述 类型 默认值 条件 id 帖子 Id Long 必须 title 文章标题 String 必须 content 帖子内容 String 必须 5.11.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/article/modify 请求头:Content-Type: application/x-www-form-urlencoded 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": null }5.11.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.12 点赞5.12.1 参数要求参数名 描述 类型 默认值 条件 id 帖子 Id long 必须 5.12.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/article/thumbsUp 请求头:Content-Type: application/x-www-form-urlencoded 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": null }5.12.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.13 删除帖子5.13.1 参数要求参数名 描述 类型 默认值 条件 id 帖子 Id long 必须 5.13.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/article/delete 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": null }5.13.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.14 获取用户的帖子列表 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.15 回复帖子5.15.1 参数要求参数名 描述 类型 默认值 条件 articleId 帖子 Id Long 必须 content 回复内容 String 必须 5.15.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/reply/create 请求头:Content-Type: application/x-www-form-urlencoded 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": null }5.15.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.16 获取回复列表5.16.1 参数要求参数名 描述 类型 默认值 条件 articleId 帖子 Id Long 必须 5.16.2 接口规范代码语言:javascript复制请求方式:GET 请求 URL:http://127.0.0.1:58080/reply/getReplies 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": [ { "id": 9, "articleId": 1, "postUserId": 2, "content": "回复没试", "likeCount": 0, "state": 0, "createTime": "2023-07-09 06:39:45", "updateTime": "2023-07-09 06:39:45", "user": { "id": 2, "nickname": "bitgirl", "phoneNum": null, "email": null, "gender": 2, "avatarUrl": null } } ] }5.16.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.17 发送站内信5.17.1 参数要求参数名 描述 类型 默认值 条件 receiveUserId 接收用户 Id Long 必须 content 站内信内容 String 必须 5.17.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/message/send 请求头:Content-Type: application/x-www-form-urlencoded { "code": 0, "message": "成功", "data": null }5.17.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.18 获取未读消息个数5.18.1 参数要求无 5.18.2 接口规范代码语言:javascript复制请求方式:GET 请求 URL:http://127.0.0.1.41:58080/message/getUnreadCount 响应状态码:200 Content-Type:application/json {"code":0,"message":"成功","data":1}5.18.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.19 查询用户的所有站内信5.19.1 参数要求无 5.19.2 接口规范代码语言:javascript复制请求方式:GET 请求 URL:http://127.0.0.1:58080/message/getAll 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": [ { "id": 11, "postUserId": 32, "receiveUserId": 3, "content": "真的可以发出去吗\n", "state": 2, "createTime": "2023-06-20 11:21:09", "updateTime": "2023-06-25 11:24:38", "postUser": { "id": 32, "nickname": "ljl", "phoneNum": null, "email": null, "gender": 2, "avatarUrl": null } }, { "id": 10, // 其余消息数据(因截图未完全展示,此处省略) } ] }5.19.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.20 更新为已读5.20.1 参数要求参数名 描述 类型 默认值 条件 id 站内信 Id long 必须 5.20.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/message/markRead 请求头:Content-Type: application/x-www-form-urlencoded 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": null }5.20.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互 5.21 回复站内信5.21.1 参数要求参数名 描述 类型 默认值 条件 repliedId 站内信 Id Long 必须 content 内容 String 必须 5.21.2 接口规范代码语言:javascript复制请求方式:POST 请求 URL:http://127.0.0.1:58080/message/reply 请求头:Content-Type: application/x-www-form-urlencoded 响应状态码:200 Content-Type:application/json { "code": 0, "message": "成功", "data": null }5.21.3 实现流程 在Mapper.xml中编写SQL语句 在Mapper.java中定义方法 定义Service接口 实现Service接口 单元测试 Controller实现方法并对外提供API接口 实现前端逻辑,完成前后端交互
