Gitee仓库链接:https://gitee.com/suhuamo/web-spring-boot-starter
Github仓库链接:https://github.com/suhuamo/web-spring-boot-starter
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F0MVt0nE-1686387710446)(null#pic_center)]](https://1000bd.com/contentImg/2024/04/11/db440bb40469bc5b.png)
mvn clean install打包到本地仓库中。pom.xml中添加如下依赖java -version 看看当前配置是否为jdk17。 <dependency>
<groupId>com.suhuamogroupId>
<artifactId>web-spring-boot-starterartifactId>
<version>1.0.0version>
dependency>
本项目已经上传到了jitPack的中央仓库中,故用户可以直接通过maven下拉使用,pom.xml中的配置如下,
<repositories>
<repository>
<id>jitpack.ioid>
<url>https://www.jitpack.iourl>
repository>
repositories>
<dependencies>
<dependency>
<groupId>com.github.suhuamogroupId>
<artifactId>web-spring-boot-starterartifactId>
<version>1.0.0version>
dependency>
dependencies>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<artifactId>spring-boot-starter-parentartifactId>
<groupId>org.springframework.bootgroupId>
<version>3.0.0version>
parent>
<groupId>com.suhuamo.testgroupId>
<artifactId>springboot-test01artifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>17maven.compiler.source>
<maven.compiler.target>17maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<repositories>
<repository>
<id>jitpack.ioid>
<url>https://www.jitpack.iourl>
repository>
repositories>
<dependencies>
<dependency>
<groupId>com.github.suhuamogroupId>
<artifactId>web-spring-boot-starterartifactId>
<version>1.0.0version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.mysqlgroupId>
<artifactId>mysql-connector-jartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
dependencies>
project>
在application.properties或者application.yml中做如下的配置,即文件中只需要如下参数即可
,其他参数如jdbc的链接,mybaits的配置在本项目的config目录中的配置文件已经配置好了。
server:
port: 20000
# spring相关配置
spring:
#数据源配置
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/springboot?useSSL=false&characterEncoding=utf8&serverTimezone=UTC&
# web-starter相关配置
suhuamo:
web:
mybatis:
# 生成的包路径
parent: com.suhuamo.test
# 需要自动生成代码的数据库表
tables:
- tbl_dept
- tbl_emp
# 生成代码时的java类去掉前缀,可为空
tablePrefix:
- tbl_
以上配置完毕后,就可以创建一个启动运行类和Test类进行基础代码的自动生成和项目的运行,代码如下:
package com.suhuamo.test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author suhuamo
* @date 2023-06-08
* @slogan 也许散落在浩瀚宇宙的小行星们也知道
*/
@MapperScan("com.suhuamo.test.mapper")
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
package com.suhuamo.test;
import com.suhuamo.web.mybatis.MyBatisService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
/**
* @author suhuamo
* @date 2023-06-08
* @slogan 也许散落在浩瀚宇宙的小行星们也知道
*/
@SpringBootTest
public class MainTest {
@Autowired
MyBatisService myBatisService;
@Test
public void GeneratorCodeTest() throws IOException {
myBatisService.generatorCode();
}
}
注意:Test类一定得和@SpringBootApplication所在的类(即启动类)处于同一个路径,否则Test类运行是不会生效的,位置如图

点击运行 Test类中的GeneratorCodeTest 方法后可发现代码已自动生成:如下

目前整个系统分为两大模块
主要用于实现系统的增删改查自动生成功能,是默认包含的,不会影响spring或被spring影响。
每一个数据表都包含了多个实体类,分成很多个是为了前后端交互方便,比如添加的接口是添加单独的DTO,那么这个DTO对应的所有字段就是前端需要给后端的字段,而不需要后端反复给前端说这个实体类有哪些字段是要用的,哪些字段是不需要用的。而且字段少了,也减少了传输的消耗。
AddDTO:用于添加接口接受前端的数据QueryDTO:用于添加接口接受前端的数据UpdateDTO:用于添加接口接受前端的数据![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZOrbJTV-1686387412332)(img_3.png)]](https://1000bd.com/contentImg/2024/04/11/30fad04a2cb1680a.png)
baseMappervalidData():校验数据,目前只用于判空,但逻辑应该自己处理,比如user信息的name一定不能为空,dept的name长度必须在2~10之间,故建议用户重写每一个service中的该方法。getQueryWrapper():获取一个QueryWrapper,用于分页查询中的条件判断,传入参数为对应的查询实体类,目前返回的是空,没有进行逻辑处理,建议用户重写该方法。poToVO():将数据库实体类转换为VO实体类,即匹配字段相同,如果VO有需要自定义的参数,那么建议重写方法。dtoToPO():将DTO实体类转换为数据库实体类,即匹配字段相同,如果DTO有自定义的参数,那么建议重写方法。pageVO(): 与 page() 方法相同使用,只不过返回的类型为VO实体类,而不是数据库实体类![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qEyMW3x2-1686387412334)(img_4.png)]](https://1000bd.com/contentImg/2024/04/11/4e73bfd4b56980e0.png)
baseServiceadd:接口名称:{entity}/add、Post方法、添加数据接口,传入参数为entityAddDTOdelete:接口名称:{entity}/delete、Post方法、删除数据接口,传入参数为DeleteDTOupdate:接口名称:{entity}/update、Post方法、更新数据接口,传入参数为entityUpdateDTOgetById:接口名称:{entity}/get、Get方法、根据id查询数据接口,传入参数为 Long id,返回数据库实体类getVOById:接口名称:{entity}/get/vo、Get方法、根据id查询数据接口,传入参数为 Long id,返回VO实体类getListByPage:接口名称:{entity}/list/page、Post方法、分页查询接口,传入参数为PageRequest,返回分页数据getVOListByPage:接口名称:{entity}/list/page/vo、Post方法、分页查询接口,传入参数为PageRequest,返回分页数据 包含了Jwt鉴权、异常处理、错误页面跳转等,可以通过yml进行配置开启/关闭,默认所有的模块都是默认开启的,可以通过配置suhuamo.web.enable = false进行统一关闭
用于处理接口的权限问题,来判断用户是否进行过登录,如果未登录,则不放行调用接口,只给登录过的用户访问接口,但也可以通过suhuamo.web.jwt.excludePathPatterns来放行哪些接口不需要权限所有状态都可以调用。原理是后端通过JwtService生成了一个token值(可以是根据userId生成的)传给前端,然后每次前端请求时都需要在请求头中附带该token,在拦截器中会判断前端的该次请求是否附带了token,并且token是否真实有效,这样来判断该次接口请求是否通过。通过JwtService也可以获取token中的隐藏数据(如userId)。
在用户控制器类,添加一个登录方法,进行用户登录操作,添加一个获取登录者信息的方法,进行获取登录者信息的操作。代码如下
@Slf4j
@RestController
@RequestMapping("/dept")
public class DeptController extends WebController<Dept, DeptAddDTO, DeptUpdateDTO, DeptQueryDTO, DeptVO, DeptService> {
@Autowired
JwtService jwtService;
/**
* 用户输入账号密码进行登录,登录成功返回token给前端
* @param loginDTO
* @return BaseResponse
*/
@GetMapping("/login")
public BaseResponse<String> login(@RequestBody DeptLoginDTO loginDTO) {
if(loginDTO == null) {
throw new CustomException(CodeEnum.PARAM_ERROR);
}
// 判断输入的数据在数据库中是否有对应的对象
Dept dept = baseService.login(loginDTO);
// 如果有,则登录成功,返回token给前端
if(Objects.isNull(dept)) {
// 根据id创建一个token
String token = jwtService.createJwt(String.valueOf(dept.getId()));
return BaseResponse.ok(token);
} else {
return BaseResponse.error(CodeEnum.PARAM_ERROR);
}
}
/**
* 获取当前登录者的信息,返回vo封装类
* @param token
* @return BaseResponse
*/
@GetMapping("/login/info/vo")
public BaseResponse<String> loginInfo(@RequestParam("token") String token) {
// 将token转换为claims数据
Claims claims = jwtService.parseJwt(token);
// claims数据解析出创建token的id
String id = claims.getId();
Dept dept = baseService.getById(id);
// 返回vo封装类
return BaseResponse.ok(baseService.poToVO(dept));
}
/**
* 向 WebController 注入所需的service接口
* @param deptService
* @return null
*/
@Autowired
public DeptController(DeptService deptService) {
setBaseService(deptService);
}
}
suhuamo:
web:
# 登录鉴权的配置
jwt:
# 是否启用jwt,默认为ture,关闭则写false
enable: true
# 放行端口,即这些端口不需要登录也能访问,建议注册、登录等接口都放行
excludePathPatterns:
- /user/login
- /user/register
# 其他都是不太重要的属性,可以细看项目,有详细注释
当前后端分离时,前端的项目是无法直接请求调用后端的接口的,会报错203,xhr跨域问题,需要在前端或者后端进行相对应的配置才能解决该问题,这里后端的后端自定义了可选择的ip:port地址、方法类型、请求头调用该项目的接口。
一定要记得配置 suhuamo.web.cors.allowedOrigins参数,否则你会忘了为什么开启了该模块前端也没法访问该项目的接口
suhuamo:
web:
# 跨域的配置
cros:
# 是否启用cros,默认为ture,关闭则写false
enable: true
# 白名单的ip:port,允许调用该项目接口的地址
allowedOrigins:
- http://localhost:9528
由于由异常有很多种,但是我们不仅用了系统给的异常,大部分时间也用了我们自定义的异常,对这些异常不可能每一个都专门去处理,故需要一个统一异常处理的地方,使得每个地方只需要 throw 我们自定义的异常,就不需要在管了,让统一异常处理的地方去处理这些异常即可,这里我们将统一异常返回的值都封装为了 BaseResponse,这样方便前端接受
在想要抛出异常的地方,抛出异常即可,如
if(loginDTO == null) {
throw new CustomException(CodeEnum.PARAM_ERROR);
}
suhuamo:
web:
# 统一异常的配置
exception:
# 是否启用cros,默认为ture,关闭则写false
enable: true
在调用接口或者跳转页面时,系统给出的报错数据是系统自定义的,和我们的BaseResponse格式不一样,不便于我们处理数据,故该项目中对这些错误的接口调用或者的页面跳转都做了相应的处理,使得符合我们的返回值规范
不关闭该模块就是正常的使用了
suhuamo:
web:
# 错误页面的配置
error-controller:
# 是否启用cros,默认为ture,关闭则写false
enable: true
一般来说,项目的接口的请求都需要进行日志的记录,这样查询错误或者查看优化的时候都比较方便
在方法上面添加注解 @LogExecutionTime,即可将该方法的运行日志记录下来,目前只能添加在方法上面记录,后续准备添加到类上面,一键实现该类下的所有方法进行记录
待补充
待补充
待补充