• 【企业级SpringBoot单体项目模板】 —— 全局配置


    • 😜           是江迪呀
    • ✒️本文关键词SpringBoot模版企业级
    • ☀️每日   一言你坚持下来了,而别人坚持不下来,这就是你的资本。


    上回我们创建了一个SpringBoot项目并且连接了数据库整合了MyBatis-plus框架。今天我们来添加一些公共的东西如:全局异常配置、返回体配置。

    本次需要的依赖:

    <dependency>
     <groupId>org.projectlombokgroupId>
       <artifactId>lombokartifactId>
       <version>1.16.16version>
    dependency>
    <dependency>
       <groupId>com.alibabagroupId>
       <artifactId>fastjsonartifactId>
       <version>1.2.75version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    本节最终项目结构:

    在这里插入图片描述

    一、全局异常配置

    在一个项目中我们常常需要处理一些业务异常,自定义一些状态码,SpringBoot框架中也有对应的方法供我们使用,但是为方便后续的扩展我们还是要自定义一个全局异常。

    1.1 全局异常处理

    @ControllerAdvice
    @Slf4j
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(value = BusinessException.class)
        @ResponseBody
        public Response businessExceptionHandler(HttpServletRequest request, BusinessException e){
            log.error("发生业务异常!原因是:{}",e.getErrorMsg());
            return Response.error(e.getErrorCode(),e.getErrorMsg());
        }
    
        /**
         * 处理空指针的异常
         * @param req
         * @param e
         * @return
         */
        @ExceptionHandler(value =NullPointerException.class)
        @ResponseBody
        public Response exceptionHandler(HttpServletRequest req, NullPointerException e){
            log.error("发生空指针异常!原因是:",e);
            return Response.error(ResultEnum.BIZ_EXCEPTION.getValue());
        }
    
        /**
         * 处理其他异常
         * @param req
         * @param e
         * @return
         */
        @ExceptionHandler(value =Exception.class)
        @ResponseBody
        public Response exceptionHandler(HttpServletRequest req, Exception e){
            log.error("系统异常!原因是:",e);
            return Response.error(ResultEnum.BIZ_EXCEPTION.getValue());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • @ExceptionHandler(value = BusinessException.class) 代码中的 value值就是 处理业务异常类

    1.2 处理业务异常类

    public class BusinessException extends RuntimeException {
        private static final long serialVersionUID = 1L;
    
        /**
         * 错误码
         */
        protected String errorCode;
        /**
         * 错误信息
         */
        protected String errorMsg;
    
        public BusinessException() {
            super();
        }
    
        public BusinessException(String errorMsg) {
            super(errorMsg);
            this.errorMsg = errorMsg;
            this.errorCode = ResultEnum.FAILED.getCode();
        }
    
        public BusinessException(String errorCode, String errorMsg) {
            super(errorCode);
            this.errorCode = errorCode;
            this.errorMsg = errorMsg;
        }
    
        public BusinessException(String errorCode, String errorMsg, Throwable cause) {
            super(errorCode, cause);
            this.errorCode = errorCode;
            this.errorMsg = errorMsg;
        }
    
    
        public String getErrorCode() {
            return errorCode;
        }
    
        public void setErrorCode(String errorCode) {
            this.errorCode = errorCode;
        }
    
        public String getErrorMsg() {
            return errorMsg;
        }
    
        public void setErrorMsg(String errorMsg) {
            this.errorMsg = errorMsg;
        }
    
        public String getMessage() {
            return errorMsg;
        }
    
        @Override
        public Throwable fillInStackTrace() {
            return this;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    1.3 状态码枚举类

    public enum ResultEnum {
        SUCCESS("0","执行成功"),
        FAILED("-1","执行失败"),
        BIZ_EXCEPTION("500","系统异常"),
        IDENTITY_IS_OVERDUE("1","身份过期"),
         //可以继续扩展定义
        ;
        private String code;
        private String value;
    
        ResultEnum(String code, String value) {
            this.code = code;
            this.value = value;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注意:需要继承RuntimeException异常,因为我们处理的业务异常全部都是运行时异常。

    1.3 使用

    在需要抛出业务异常的地方:

    //自定义提示信息
    throw new BusinessException("发生了业务异常!");
    //自定义状态码
    throw new BusinessException("502","发生了业务异常!");
    
    • 1
    • 2
    • 3
    • 4
    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
        @Override
        public List<UserVO> queryUserInfo() {
            int a = 1;
            if(a == 1){
                throw new BusinessException("502","发生了业务异常!");
            }
            return baseMapper.queryUserInfo();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    结果:
    在这里插入图片描述

    二、返回体配置

    在上篇文章中我们在controller层返回的值直接是个集合:
    在这里插入图片描述
    这样是不符合规范的,我们需要定义一个含有code状态码、msg提示信息、data数据这三者的返回体。

    2.1 返回体类

    @Getter
    @Setter
    public class Response {
        /**
         * 响应码
         */
        private String code;
    
        /**
         * 响应消息
         */
        private String msg;
    
        /**
         * 响应结果
         */
        private Object result;
    
        /**
         * 成功
         *
         * @return
         */
        public static Response success() {
            return new Response(ResultEnum.SUCCESS.getCode(),ResultEnum.SUCCESS.getValue(),null);
        }
        /**
         * 成功
         *
         * @return
         */
        public static Response success(String msg) {
            return new Response(ResultEnum.SUCCESS.getCode(),msg,null);
        }
        public Response() {
        }
        public Response(String code, String msg, Object result) {
            this.code = code;
            this.msg = msg;
            this.result = result;
        }
    
        /**
         * 成功
         * @param data
         * @return
         */
        public static Response success(Object data) {
            Response rb = new Response();
            rb.setCode(ResultEnum.SUCCESS.getCode());
            rb.setMsg(ResultEnum.SUCCESS.getValue());
            rb.setResult(data);
            return rb;
        }
    
        /**
         * 失败
         */
        public static Response error(String code, String message) {
            Response rb = new Response();
            rb.setCode(code);
            rb.setMsg(message);
            rb.setResult(null);
            return rb;
        }
    
        /**
         * 失败
         */
        public static Response error(String message) {
            Response rb = new Response();
            rb.setCode(ResultEnum.FAILED.getCode());
            rb.setMsg(message);
            rb.setResult(null);
            return rb;
        }
    
        @Override
        public String toString() {
            return JSONObject.toJSONString(this);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    2.2 抽象controller

    public abstract class AbstractController {
        public Response returnSuccess(){
            return Response.success();
        }
        public Response returnSuccess(Object data){
            return Response.success(data);
        }
        public Response returnSuccess(String msg){
            return Response.success(msg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我们需要每个controller都继承AbstractController

    2.3 使用

    @RestController
    @RequestMapping("/user")
    public class UserController extends AbstractController {
        @Autowired
        private UserService userService;
    
        @GetMapping("/users")
        public Response users(){
            return returnSuccess(userService.queryUserInfo());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试:
    在这里插入图片描述

    三、基础类

    3.1 分页基础类

    @Getter
    @Setter
    public class BasePageDTO{
     	/**
         * 页数
         */
        @Min(1)
        private Integer pageNum;
    	/**
         * 页数
         */
        private Integer pageSize;
    	/**
         * 排序规则
         */
        private String sortOrder;
    	/**
         * 排序字段
         */
        private String sortProp;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这个分页的基础类在你需要分页的入参QO或者DTO中继承:

    public class UserPageQO extends BasePageDTO {}
    
    • 1

    3.2 实体类基础类(可以不使用)

    实体类基础类中包含数据库表中都有的字段,比如 是否删除标识、创建时间、创建人、修改时间、修改人等,根据自己实际情况做出调整。

    @Getter
    @Setter
    public class BaseEntity {
        @TableId(type = IdType.UUID)
        private String id;
        @TableField("delete_flag")
        private Boolean deleteFlag;
        @TableField("create_time")
        private Date createTime;
        @TableField("modify_time")
        private Date modifyTime;
        @TableField("create_user")
        private String createUser;
        @TableField("modify_user")
        private String modifyUser;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    全部的实体类都要继承BaseEntity:

    @TableName("user")
    public class User extends BaseEntity {
        private String name;
    
        private Integer age;
    
        public User() {
        }
    
        public User(Long id, String name, Integer age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    实体类中就可以省略掉BaseEntity 已经存在的属性,比如id。

  • 相关阅读:
    (yum+内网)centos7两种方式安装jdk11
    请问一下测试过来人,现在学来得及吗😫
    11月千言最新评测推荐,覆盖中文对话、视频语义理解、可信AI等前沿方向
    SystemVerilog学习 (10)——线程控制
    ffmpeg 从avio_read 到 file_read
    时隔3天,我终于理解了四个盘子的汉诺塔问题(Java实现)
    locust的使用
    【Linux】编译器 gcc/g++
    处理服务器返回的utc 时间转正标准时间
    3、Python量化交易-股票数据预处理&跌幅买卖收益分析
  • 原文地址:https://blog.csdn.net/qq_42785250/article/details/132956313