01-05的可正确运行的完整代码放在百度云盘,后续操作在此基础上进行:
链接:https://pan.baidu.com/s/1fB7E0hXW34ayKFzGphOhMQ?pwd=1us3
提取码:1us3
统一返回结果工具类
一、定义统一返回结果的工具类
1. 定义枚举类ResultCodeEnum
package com.yun.utils.common;
import lombok.Getter;
/**
* 统一返回结果状态信息类
*/
@Getter
public enum ResultCodeEnum {
SUCCESS(200,"成功"),
FAIL(201, "失败"),
LOGIN_ERROR(208,"认证失败")
;
private Integer code;
private String message;
private ResultCodeEnum(Integer code,String message){
this.code = code;
this.message = message;
}
}
2. 定义结果类Result<T>.class
package com.yun.utils.common;
import lombok.Data;
/*
* @paragram: myyunshangbangong
* @description: 统一结果返回类
* @author:
* @create: 2024-01-11
*/
@Data
public class Result<T> {
private Integer code;//状态码
private String message;//返回信息
private T data;//数据
//私有化
private Result() {}
//封装返回的数据
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = new Result<>();
//封装数据
if(body != null) {
result.setData(body);
}
//状态码
result.setCode(resultCodeEnum.getCode());
//返回信息
result.setMessage(resultCodeEnum.getMessage());
return result;
}
//成功
public static<T> Result<T> ok() {
return build(null,ResultCodeEnum.SUCCESS);
}
public static<T> Result<T> ok(T data) {
return build(data,ResultCodeEnum.SUCCESS);
}
//失败
public static<T> Result<T> fail() {
return build(null,ResultCodeEnum.FAIL);
}
public static<T> Result<T> fail(T data) {
return build(data,ResultCodeEnum.FAIL);
}
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
}
3. 修改controller进行测试
package com.yun.oa.controller;
import com.yun.model.model.system.SysRole;
import com.yun.oa.service.SysRoleService;
import com.yun.utils.common.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/*
* @paragram: myyunshangbangong
* @description:
* @author:
* @create: 2024-01-11
*/
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
// 注入service
@Autowired
private SysRoleService sysRoleService;
// // 查询所有角色
// @GetMapping("/findAll")
// public List<SysRole> findAll(){
// List<SysRole> sysRoles = sysRoleService.list();
// return sysRoles;
// }
// 查询所有角色
/**
* 统一返回数据结果
* @return
*/
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> sysRoles = sysRoleService.list();
return Result.ok(sysRoles);
}
}
结果展示
二、整合knife4j框架
位置:knife4j属于公共资源,集成到service-util模块中
1. 添加依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
2. 添加knife4j配置类
位置
代码(固定内容,除标红位置需要和自己项目一致外其他不变)
以下内容可不修改
package com.yun.utils.service.knife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
import java.util.ArrayList;
import java.util.List;
/**
* knife4j配置信息
*/
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfig {
@Bean
public Docket adminApiConfig(){
List<Parameter> pars = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
tokenPar.name("token")
.description("用户token")
.defaultValue("")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build();
pars.add(tokenPar.build());
//添加head参数end
Docket adminApi = new Docket(DocumentationType.SWAGGER_2)
.groupName("adminApi")
.apiInfo(adminApiInfo())
.select()
//只显示admin路径下的页面
.apis(RequestHandlerSelectors.basePackage("com.yun"))
.paths(PathSelectors.regex("/admin/.*"))
.build()
.globalOperationParameters(pars);
return adminApi;
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("后台管理系统-API文档")
.description("本文档描述了后台管理系统微服务接口定义")
.version("1.0")
.contact(new Contact("yun", "http://yun.com", "yun@qq.com"))
.build();
}
}
3. 修改controller代码
package com.yun.oa.controller;
import com.yun.model.model.system.SysRole;
import com.yun.oa.service.SysRoleService;
import com.yun.utils.common.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/*
* @paragram: myyunshangbangong
* @description:
* @author:
* @create: 2024-01-11
*/
@Api(tags = "角色管理接口")
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
// 注入service
@Autowired
private SysRoleService sysRoleService;
// // 查询所有角色
// @GetMapping("/findAll")
// public List<SysRole> findAll(){
// List<SysRole> sysRoles = sysRoleService.list();
// return sysRoles;
// }
/**
* 统一返回数据结果
* 查询所有角色
* @return
*/
@ApiOperation("查询所有角色")
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> sysRoles = sysRoleService.list();
return Result.ok(sysRoles);
}
}
4. 运行访问
http://localhost:8080/doc.html
结果如下
三、条件分页查询
1. 创建分页插件
创建配置类:MybatisPlusConfig
修改为自己使用的数据库
package com.yun.utils.service.mp;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/*
* @paragram: myyunshangbangong
* @description: MyBatisPlus配置类
* @author:
* @create: 2024-01-11
*/
@Configuration
@ComponentScan("com.yun")
public class MybatisPlusConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
2. 编写controller中的分页方法并调用service中的方法
package com.yun.oa.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yun.model.model.system.SysRole;
import com.yun.model.vo.system.SysRoleQueryVo;
import com.yun.oa.service.SysRoleService;
import com.yun.utils.common.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/*
* @paragram: myyunshangbangong
* @description:
* @author:
* @create: 2024-01-11
*/
@Api(tags = "角色管理接口")
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
// 注入service
@Autowired
private SysRoleService sysRoleService;
// // 查询所有角色
// @GetMapping("/findAll")
// public List<SysRole> findAll(){
// List<SysRole> sysRoles = sysRoleService.list();
// return sysRoles;
// }
/**
* 统一返回数据结果
* 查询所有角色
* @return
*/
@ApiOperation("查询所有角色")
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> sysRoles = sysRoleService.list();
return Result.ok(sysRoles);
}
/**
* 条件分页查询
* page 当前页 limit 每页显示记录数
* SysRoleQueryVo 条件对象
* @return
*/
@ApiOperation("条件分页查询")
@GetMapping("{page}/{limit}")
public Result pageQueryRole(@PathVariable Long page,
@PathVariable Long limit,
SysRoleQueryVo sysRoleQueryVo){
// 调用service中的方法进行实现
// 1. 创建一个怕个对象,传递分页相关参数
Page<SysRole> pageParam = new Page<>(page,limit);
// 2. 封装条件,判断条件是否为空,不为空则进行分装
LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
String roleName = sysRoleQueryVo.getRoleName();
if( !StringUtils.isEmpty(roleName) ){
// 进行封装
wrapper.like(SysRole::getRoleName,roleName);
}
// 3. 调用方法实现
Page<SysRole> page1 = sysRoleService.page(pageParam, wrapper);
return Result.ok(page1);
}
}
需要注意的点:
3. 执行
http://localhost:8080/doc.html
结果
数据库的数据情况
role_name含有2的是id=2和id=11,但id=2被删除了(is_deleted=1)因此查询出来一个数据
四、其他增删改查的方法
package com.yun.oa.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yun.model.model.system.SysRole;
import com.yun.model.vo.system.SysRoleQueryVo;
import com.yun.oa.service.SysRoleService;
import com.yun.utils.common.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/*
* @paragram: myyunshangbangong
* @description:
* @author:
* @create: 2024-01-11
*/
@Api(tags = "角色管理接口")
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
// 注入service
@Autowired
private SysRoleService sysRoleService;
// // 查询所有角色
// @GetMapping("/findAll")
// public List<SysRole> findAll(){
// List<SysRole> sysRoles = sysRoleService.list();
// return sysRoles;
// }
/**
* 统一返回数据结果
* 查询所有角色
* @return
*/
@ApiOperation("查询所有角色")
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> sysRoles = sysRoleService.list();
return Result.ok(sysRoles);
}
/**
* 条件分页查询
* page 当前页 limit 每页显示记录数
* SysRoleQueryVo 条件对象
* @return
*/
@ApiOperation("条件分页查询")
@GetMapping("{page}/{limit}")
public Result pageQueryRole(@PathVariable Long page,
@PathVariable Long limit,
SysRoleQueryVo sysRoleQueryVo){
// 调用service中的方法进行实现
// 1. 创建一个怕个对象,传递分页相关参数
Page<SysRole> pageParam = new Page<>(page,limit);
// 2. 封装条件,判断条件是否为空,不为空则进行分装
LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
String roleName = sysRoleQueryVo.getRoleName();
if( !StringUtils.isEmpty(roleName) ){
// 进行封装
wrapper.like(SysRole::getRoleName,roleName);
}
// 3. 调用方法实现
Page<SysRole> page1 = sysRoleService.page(pageParam, wrapper);
return Result.ok(page1);
}
// 添加角色
@ApiOperation("添加角色")
@PostMapping("save")
public Result save(@RequestBody SysRole sysRole){
// 调用service中的方法实现
boolean is_success = sysRoleService.save(sysRole);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
// 修改角色-根据id查询
@ApiOperation("根据id进行查询")
@GetMapping("get/{id}")
public Result get(@PathVariable Long id){
SysRole sysRole = sysRoleService.getById(id);
return Result.ok(sysRole);
}
// 修改角色-最终修改
@ApiOperation("修改角色-最终修改")
@PutMapping("update")
public Result update(@RequestBody SysRole sysRole){
// 调用service中的方法实现
boolean is_success = sysRoleService.updateById(sysRole);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
// 根据id删除
@ApiOperation("根据id删除")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id){
boolean is_success = sysRoleService.removeById(id);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
// 批量删除
// 前端数组[1,2,3]
@ApiOperation("批量删除")
@DeleteMapping("batchRemove")
public Result batchRemove(@RequestBody List<Long> idList){
boolean is_success = sysRoleService.removeByIds(idList);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
}
五、数据时间格式矫正与修改
在配置文件中修改:application-dev.yml
server:
port: 8080
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #查看日志
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/guigu-oa?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8
username: root
password: 111111
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
时间修改正确
六、统一异常处理
1. 创建自定义异常类:MyException
package com.yun.utils.service.exception;
import com.yun.utils.common.ResultCodeEnum;
import lombok.Data;
@Data
public class GuiguException extends RuntimeException {
private Integer code;//状态码
private String msg;//描述信息
public GuiguException(Integer code,String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
/**
* 接收枚举类型对象
* @param resultCodeEnum
*/
public GuiguException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
this.msg = resultCodeEnum.getMessage();
}
@Override
public String toString() {
return "GuliException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}
2. 异常处理方法
位置:
代码:
package com.yun.utils.service.exception;
import com.yun.utils.common.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.nio.file.AccessDeniedException;
@ControllerAdvice
public class GlobalExceptionHandler {
//全局异常处理,执行的方法
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
e.printStackTrace();
return Result.fail().message("执行全局异常处理...");
}
//特定异常处理
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public Result error(ArithmeticException e) {
e.printStackTrace();
return Result.fail().message("执行特定异常处理...");
}
//自定义异常处理
@ExceptionHandler(MyException.class)
@ResponseBody
public Result error(MyException e) {
e.printStackTrace();
return Result.fail().code(e.getCode()).message(e.getMsg());
}
}
3. 修改controller,模拟异常
package com.yun.oa.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yun.model.model.system.SysRole;
import com.yun.model.vo.system.SysRoleQueryVo;
import com.yun.oa.service.SysRoleService;
import com.yun.utils.common.Result;
import com.yun.utils.service.exception.MyException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/*
* @paragram: myyunshangbangong
* @description:
* @author:
* @create: 2024-01-11
*/
@Api(tags = "角色管理接口")
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController {
// 注入service
@Autowired
private SysRoleService sysRoleService;
// // 查询所有角色
// @GetMapping("/findAll")
// public List<SysRole> findAll(){
// List<SysRole> sysRoles = sysRoleService.list();
// return sysRoles;
// }
/**
* 统一返回数据结果
* 查询所有角色
* @return
*/
@ApiOperation("查询所有角色")
@GetMapping("/findAll")
public Result findAll(){
List<SysRole> sysRoles = sysRoleService.list();
return Result.ok(sysRoles);
}
/**
* 条件分页查询
* page 当前页 limit 每页显示记录数
* SysRoleQueryVo 条件对象
* @return
*/
@ApiOperation("条件分页查询")
@GetMapping("{page}/{limit}")
public Result pageQueryRole(@PathVariable Long page,
@PathVariable Long limit,
SysRoleQueryVo sysRoleQueryVo){
// 调用service中的方法进行实现
// 1. 创建一个怕个对象,传递分页相关参数
Page<SysRole> pageParam = new Page<>(page,limit);
// 2. 封装条件,判断条件是否为空,不为空则进行分装
LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
String roleName = sysRoleQueryVo.getRoleName();
if( !StringUtils.isEmpty(roleName) ){
// 进行封装
wrapper.like(SysRole::getRoleName,roleName);
}
// 3. 调用方法实现
Page<SysRole> page1 = sysRoleService.page(pageParam, wrapper);
return Result.ok(page1);
}
// 添加角色
@ApiOperation("添加角色")
@PostMapping("save")
public Result save(@RequestBody SysRole sysRole){
// 调用service中的方法实现
boolean is_success = sysRoleService.save(sysRole);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
// 修改角色-根据id查询
@ApiOperation("根据id进行查询")
@GetMapping("get/{id}")
public Result get(@PathVariable Long id){
// 模拟异常效果
// 全局+特定 先扫描特定然后扫描全局
// int i = 10/0;
// 自定义异常处理
try {
int j = 10/0;
}catch (Exception e){
// 抛出自定义异常
throw new MyException(20001,"执行了自定义异常");
}
SysRole sysRole = sysRoleService.getById(id);
return Result.ok(sysRole);
}
// 修改角色-最终修改
@ApiOperation("修改角色-最终修改")
@PutMapping("update")
public Result update(@RequestBody SysRole sysRole){
// 调用service中的方法实现
boolean is_success = sysRoleService.updateById(sysRole);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
// 根据id删除
@ApiOperation("根据id删除")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id){
boolean is_success = sysRoleService.removeById(id);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
// 批量删除
// 前端数组[1,2,3]
@ApiOperation("批量删除")
@DeleteMapping("batchRemove")
public Result batchRemove(@RequestBody List<Long> idList){
boolean is_success = sysRoleService.removeByIds(idList);
if(is_success){
return Result.ok();
}else {
return Result.fail();
}
}
}
3. 自定义异常处理结果