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

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


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

本次需要的依赖:

<dependency>
 <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.16.16</version>
</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.75</version>
</dependency>

本节最终项目结构:

在这里插入图片描述

一、全局异常配置

在一个项目中我们常常需要处理一些业务异常,自定义一些状态码,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());
    }
}

  • @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.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;
    }
}

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

1.3 使用

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

//自定义提示信息
throw new BusinessException("发生了业务异常!");
//自定义状态码
throw new BusinessException("502","发生了业务异常!");
@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();
    }
}

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

二、返回体配置

在上篇文章中我们在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);
    }
}

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);
    }
}

我们需要每个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());
    }
}

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

三、基础类

3.1 分页基础类

@Getter
@Setter
public class BasePageDTO{
 	/**
     * 页数
     */
    @Min(1)
    private Integer pageNum;
	/**
     * 页数
     */
    private Integer pageSize;
	/**
     * 排序规则
     */
    private String sortOrder;
	/**
     * 排序字段
     */
    private String sortProp;
  }

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

public class UserPageQO extends BasePageDTO {}

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;
}

全部的实体类都要继承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;
    }
}

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是江迪呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值