Appearance
XBase文档
后端技术栈
技术 | 说明 | 版本 |
---|---|---|
Spring Boot | 基于 Spring 框架的开发框架 | 3.1.3 |
Hibernate Validator | Jakarta Bean Validation规范定义的 Java Bean 验证框架的一个实现 | |
Mybatis Plus | Mybatis 框架的增强工具 | 3.5.3.2 |
SaToken | 轻量级的 Java 权限验证和会话管理工具1.34 | 1.34 |
Star | 一个 Java 工具仓库,奉行二八法则,只提供 20% 的最常用的工具。 | |
Tianai Captcha | Java 图片验证码库 | 1.4.1 |
SmartDoc | 基于代码注释自动接口文档生成工具 | 3.0.0 |
MySQL | 开源的关系型数据库管理系统 | 5.7及以上 |
Redis | 开源的内存数据存储系统 |
项目结构
整体项目结构如下:

xbase对外分为两个模块,分别为xbase-api-admin
和xbase-api-portal
,向前端提供接口,等同于Controller层
项目结构
xbase-api-admin
- admin管理端,为系统的超级管理端,一般建议以网络物理隔离的方式部署。
- Controller层
xbase-api-portal
- portal用户端,组织管理者和普通用户的交互均在此层。
- Controller层
xbase-service
- 包含了业务逻辑和数据库访问对象,无论是 portal 端还是 admin 端的业务,都写到这个模块中。
- Service层和Repository层
xbase-common
- 公共库,包含了工具类、常量、框架配置、model 等。
xbase-code
- 负责代码生成,可以根据数据库表来生成前后端代码。
xbase-doc
- 存放技术文档
xbase-data
- 数据库相关文档,如脚本
xbase-web
- 前端项目
模块之间依赖关系如下:
简化的架构模型

分层模型职责
Controller层
入口点,负责接收用户的请求,并将请求转发给对应的业务逻辑处理
处理用户输入的参数,进行解析、校验和转换
调用Service层来处理业务逻辑
负责响应结果的封装和返回
Service层
业务逻辑处理层,负责处理业务逻辑和协调各个 Repository层的操作
业务逻辑处理
事务控制
注意业务逻辑的封装重用和扩展性
Repository层
数据访问层,负责与数据库或其他数据存储进行交互
封装了对数据的持久化操作,包括查询、增加、修改和删除等
通常提供一些接口或方法,供 Service 层调用以执行数据库操作
API文档生成
文档生成使用smart-doc,因此需要按照 JavaDoc 标准书写注释
注释要求
类/接口、字段/属性、方法上的注释,强制使用文档注释 /** /,禁止使用单行注释 // 和块注释 / */
添加smart-doc-maven-plugin插件
- 本项目为多模块项目,建议将插件在父项目pom中定义,在需要生成文档的子项目中增加插件引用
xml
<!--父pom.xml-->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.ly.smart-doc</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<configFile>${basedir}/src/main/resources/smart-doc.json</configFile>
<projectName>${project.description}</projectName>
<includes>
<!-- 使用了mybatis-plus的Page分页需要include所使用的源码包 -->
<include>com.baomidou:mybatis-plus-extension</include>
<!-- 使用了mybatis-plus的IPage分页需要include mybatis-plus-core-->
<include>com.baomidou:mybatis-plus-core</include>
<!-- 使用了jpa的分页需要include所使用的源码包 -->
<include>org.springframework.data:spring-data-commons</include>
</includes>
</configuration>
<executions>
<execution>
<!--如果不需要在执行编译时启动smart-doc,则将phase注释掉-->
<phase>compile</phase>
<goals>
<!--smart-doc提供了html、openapi、markdown等goal,可按需配置-->
<goal>html</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<!--父pom.xml-->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.ly.smart-doc</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<configFile>${basedir}/src/main/resources/smart-doc.json</configFile>
<projectName>${project.description}</projectName>
<includes>
<!-- 使用了mybatis-plus的Page分页需要include所使用的源码包 -->
<include>com.baomidou:mybatis-plus-extension</include>
<!-- 使用了mybatis-plus的IPage分页需要include mybatis-plus-core-->
<include>com.baomidou:mybatis-plus-core</include>
<!-- 使用了jpa的分页需要include所使用的源码包 -->
<include>org.springframework.data:spring-data-commons</include>
</includes>
</configuration>
<executions>
<execution>
<!--如果不需要在执行编译时启动smart-doc,则将phase注释掉-->
<phase>compile</phase>
<goals>
<!--smart-doc提供了html、openapi、markdown等goal,可按需配置-->
<goal>html</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
xml
<!--子项目pom.xml-->
<build>
<plugins>
<plugin>
<groupId>com.ly.smart-doc</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!--子项目pom.xml-->
<build>
<plugins>
<plugin>
<groupId>com.ly.smart-doc</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置smart-doc.json文档
json{ "isStrict": false, //是否开启严格模式,严格模式会检查代码注释,在2.6.3即以后的插件版本设置此项时检查到注释错误也会直接中断插件白嵌套的构建周期 "allInOne": true, //是否将文档合并到一个文件中,一般推荐为true "outPath": "./src/main/resources/static/doc", //指定文档的输出路径 "randomMock": false,//是否生成随机mock,默认false,@since 2.6.9 "coverOld": true, //是否覆盖旧的文件,主要用于mardown文件覆盖 "createDebugPage": false,//@since 2.0.0 创建一个类似swagger的可调试接口的文档页面,仅在AllInOne模式中起作用。从@2.0.1开始,对html文档,都能够生成debug页面。 "packageFilters": "",//controller包过滤,多个包用英文逗号隔开,2.2.2开始需要采用正则:com.test.controller.*,2.7.1开始支持方法级别正则:com.test.controller.TestController.* "packageExcludeFilters": "",//对packageFilters排除子包,多个包用英文逗号隔开,2.2.2开始需要采用正则:com.test.controller.res.* "md5EncryptedHtmlName": false,//只有每个controller生成一个html文件时才使用 "style":"xt256", //基于highlight.js的代码高设置,可选值很多可查看码云wiki,喜欢配色统一简洁的同学可以不设置 "framework": "spring",//smart-doc默认支持spring和dubbo框架的文档,使用默认框架不用配置,当前支持spring、dubbo、JAX-RS、solon "sortByTitle":false,//接口标题排序,默认为false,@since 1.8.7版本开始 "showAuthor":false,//是否显示接口作者名称,默认是true,不想显示可关闭 "requestFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始 "responseFieldToUnderline":true,//自动将驼峰响应字段在文档中转为下划线格式,//@since 1.8.7版本开始 "inlineEnum":true,//设置为true会将枚举详情展示到参数表中,默认关闭,//@since 1.8.8版本开始 "recursionLimit":7,//设置允许递归执行的次数用于避免一些对象解析卡主,默认是7,正常为3次以内,//@since 1.8.8版本开始 "allInOneDocFileName":"index.html",//自定义设置输出文档名称, @since 1.9.0 "requestExample":"true",//是否将请求示例展示在文档中,默认true,@since 1.9.0 "responseExample":"true",//是否将响应示例展示在文档中,默认为true,@since 1.9.0 "requestParamsTable": true, //@since 2.2.5,是否在文档中显示请求参数表,默认值为 true。 "responseParamsTable": true, //@since 2.2.5,是否在文档中显示返回参数表,默认值为 true。 "displayActualType":false,//配置true会在注释栏自动显示泛型的真实类型短类名, "revisionLogs": [{ //文档变更记录,非必须 "version": "1.0", //文档版本号 "revisionTime": "2023-11-02", //文档修订时间 "status": "create", //变更操作状态,一般为:创建、更新等 "author": "xbase team", //文档变更作者 "remarks": "desc" //变更描述 } ] }
{ "isStrict": false, //是否开启严格模式,严格模式会检查代码注释,在2.6.3即以后的插件版本设置此项时检查到注释错误也会直接中断插件白嵌套的构建周期 "allInOne": true, //是否将文档合并到一个文件中,一般推荐为true "outPath": "./src/main/resources/static/doc", //指定文档的输出路径 "randomMock": false,//是否生成随机mock,默认false,@since 2.6.9 "coverOld": true, //是否覆盖旧的文件,主要用于mardown文件覆盖 "createDebugPage": false,//@since 2.0.0 创建一个类似swagger的可调试接口的文档页面,仅在AllInOne模式中起作用。从@2.0.1开始,对html文档,都能够生成debug页面。 "packageFilters": "",//controller包过滤,多个包用英文逗号隔开,2.2.2开始需要采用正则:com.test.controller.*,2.7.1开始支持方法级别正则:com.test.controller.TestController.* "packageExcludeFilters": "",//对packageFilters排除子包,多个包用英文逗号隔开,2.2.2开始需要采用正则:com.test.controller.res.* "md5EncryptedHtmlName": false,//只有每个controller生成一个html文件时才使用 "style":"xt256", //基于highlight.js的代码高设置,可选值很多可查看码云wiki,喜欢配色统一简洁的同学可以不设置 "framework": "spring",//smart-doc默认支持spring和dubbo框架的文档,使用默认框架不用配置,当前支持spring、dubbo、JAX-RS、solon "sortByTitle":false,//接口标题排序,默认为false,@since 1.8.7版本开始 "showAuthor":false,//是否显示接口作者名称,默认是true,不想显示可关闭 "requestFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始 "responseFieldToUnderline":true,//自动将驼峰响应字段在文档中转为下划线格式,//@since 1.8.7版本开始 "inlineEnum":true,//设置为true会将枚举详情展示到参数表中,默认关闭,//@since 1.8.8版本开始 "recursionLimit":7,//设置允许递归执行的次数用于避免一些对象解析卡主,默认是7,正常为3次以内,//@since 1.8.8版本开始 "allInOneDocFileName":"index.html",//自定义设置输出文档名称, @since 1.9.0 "requestExample":"true",//是否将请求示例展示在文档中,默认true,@since 1.9.0 "responseExample":"true",//是否将响应示例展示在文档中,默认为true,@since 1.9.0 "requestParamsTable": true, //@since 2.2.5,是否在文档中显示请求参数表,默认值为 true。 "responseParamsTable": true, //@since 2.2.5,是否在文档中显示返回参数表,默认值为 true。 "displayActualType":false,//配置true会在注释栏自动显示泛型的真实类型短类名, "revisionLogs": [{ //文档变更记录,非必须 "version": "1.0", //文档版本号 "revisionTime": "2023-11-02", //文档修订时间 "status": "create", //变更操作状态,一般为:创建、更新等 "author": "xbase team", //文档变更作者 "remarks": "desc" //变更描述 } ] }
生成文档
使用mvn命令生成
bash# 生成html,其他方式参考smart-doc官方文档 mvn -Dfile.encoding=UTF-8 smart-doc:html
# 生成html,其他方式参考smart-doc官方文档 mvn -Dfile.encoding=UTF-8 smart-doc:html
使用IDEA Maven工具生成
前端请求处理
前端请求参数校验是web开发中非常重要的一项功能。它可以确保在方法调用时,传入的参数符合预期的要求,从而提高系统的稳定性和安全性。
项目选中Spring Boot默认且主流的基于Jakarta Bean Validation规范的Hibernate Validator,关于具体使用参考官方文档。
准备工作
引入依赖
xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>${spring.boot.version}</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>${spring.boot.version}</version> </dependency>
以下为常见的几种使用方式
@RequestBody
+@Validated
+Form对象校验规则
对应前端通过Body传输 applicaiton/json 对象
Form对象字段使用响应注解标识校验规则
java@Data public class UserLoginForm implements IPrint { @NotBlank(message = "用户名/手机/邮箱不能为空") private String userName; @NotBlank(message = "密码不能为空") @Pattern(regexp = ValidTool.password.regx, message = ValidTool.password.message) private String password; @NotNull(message = "登录类型不能为空") private Integer userType; }
@Data public class UserLoginForm implements IPrint { @NotBlank(message = "用户名/手机/邮箱不能为空") private String userName; @NotBlank(message = "密码不能为空") @Pattern(regexp = ValidTool.password.regx, message = ValidTool.password.message) private String password; @NotNull(message = "登录类型不能为空") private Integer userType; }
方式上增加@Validated注解
java@PostMapping("/doLogin") public BizResponseVo<UserSessionVo> doLogin(@RequestBody @Validated UserLoginForm userLoginForm) { }
@PostMapping("/doLogin") public BizResponseVo<UserSessionVo> doLogin(@RequestBody @Validated UserLoginForm userLoginForm) { }
@PathVariable
+校验规则
对应前端通过url路径传参
java@GetMapping(value = "/get/{id}") public ResultMessage<Bill> get(@PathVariable @NotNull String id) { return ResultUtil.data(billService.getById(id)); }
@GetMapping(value = "/get/{id}") public ResultMessage<Bill> get(@PathVariable @NotNull String id) { return ResultUtil.data(billService.getById(id)); }
@RequestParam
+校验规则
对应前端通过url参数传参
java@PostMapping (value = "/changeUsername") public BizResponseVo changeUsername(@RequestParam("newUserName") @NotNull(message = "用户名不能为空") String newUserName) { }
@PostMapping (value = "/changeUsername") public BizResponseVo changeUsername(@RequestParam("newUserName") @NotNull(message = "用户名不能为空") String newUserName) { }
上传文件
+数据
对应前端通过
multipart/form-data
方式传输文件和对象java@PostMapping("update") public BizResponseVo update( @Validated OrgUpdateForm orgUpdateForm, @RequestParam(value = "file", required = false) MultipartFile file ) { }
@PostMapping("update") public BizResponseVo update( @Validated OrgUpdateForm orgUpdateForm, @RequestParam(value = "file", required = false) MultipartFile file ) { }
响应返回规范
为了规范接口返回,统一错误处理,统一状态码定义,同时提供灵活扩展,项目使用了star
中的统一的返回Response模型,如下
- 普通返回模型
java
public class BizResponseVo<T> implements IPrint {
/**
* 错误编码
*/
private int code;
/**
* 操作信息
*/
private String message;
/**
* 数据
*/
private T data;
/**
* 返回时间
*/
private LocalDateTime time;
}
public class BizResponseVo<T> implements IPrint {
/**
* 错误编码
*/
private int code;
/**
* 操作信息
*/
private String message;
/**
* 数据
*/
private T data;
/**
* 返回时间
*/
private LocalDateTime time;
}
- 分页返回模型
java
public class BizPageResponseVo<T> extends BizResponseVo<T> implements IPrint {
/**
* 每页展示数据条数
*/
private long pageSize;
/**
* 当前显示的数据页编号
*/
private long pageNo;
/**
* 数据总条数
*/
private long totalNum;
/**
* 数据总页数
*/
private long totalPage;
}
public class BizPageResponseVo<T> extends BizResponseVo<T> implements IPrint {
/**
* 每页展示数据条数
*/
private long pageSize;
/**
* 当前显示的数据页编号
*/
private long pageNo;
/**
* 数据总条数
*/
private long totalNum;
/**
* 数据总页数
*/
private long totalPage;
}
放了方便使用,建议使用 star
封装的 BizTool
工具,相关示例如下
注意:
1、返回值需要指定泛型类型,这样smart-doc才能生成正常的文档
2、api接口层负责将业务模型封装成统一返回模型,服务层应只返回业务模型
普通返回示例
javapublic BizResponseVo<UserVo> viewInfo() { UserVo vo = new UserVo(); return BizTool.OK.success("查看用户基本信息成功", vo); }
public BizResponseVo<UserVo> viewInfo() { UserVo vo = new UserVo(); return BizTool.OK.success("查看用户基本信息成功", vo); }
分页返回示例
javapublic BizPageResponseVo<List<OrgVo>> orgManageList(OrgQueryForm orgQueryForm, BizPageForm pageForm) { return orgService.orgManageList(orgQueryForm,pageForm); }
public BizPageResponseVo<List<OrgVo>> orgManageList(OrgQueryForm orgQueryForm, BizPageForm pageForm) { return orgService.orgManageList(orgQueryForm,pageForm); }