SpringBoot实现统一返回值+全局异常处理

在这里首先感谢的就是程序员老罗,从他的项目里面学到了这些东西。

首先就是去创建一个SpringBoot项目,这里我就不多做赘述了

封装一个统一返回对象

java 复制代码
package com.example.demo.vo;

public class ResponseVO<T> {

    private String status;
    private Integer code;
    private String info;
    private T data;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

封装一个异常返回对象

java 复制代码
package com.example.demo.exception;
import com.example.demo.entity.enums.ResponseCodeEnum;


public class BusinessException extends RuntimeException {

    private ResponseCodeEnum codeEnum;

    private Integer code;

    private String message;

    public BusinessException(String message, Throwable e) {
        super(message, e);
        this.message = message;
    }

    public BusinessException(String message) {
        super(message);
        this.message = message;
    }

    public BusinessException(Throwable e) {
        super(e);
    }

    public BusinessException(ResponseCodeEnum codeEnum) {
        super(codeEnum.getMsg());
        this.codeEnum = codeEnum;
        this.code = codeEnum.getCode();
        this.message = codeEnum.getMsg();
    }

    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }

    public ResponseCodeEnum getCodeEnum() {
        return codeEnum;
    }

    public Integer getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    /**
     * 重写fillInStackTrace 业务异常不需要堆栈信息,提高效率.
     */
    @Override
    public Throwable fillInStackTrace() {
        return this;
    }

}

定义一个请求结果的枚举

java 复制代码
package com.example.demo.entity.enums;

public enum ResponseCodeEnum {
    CODE_200(200,"请求成功"),
    CODE_404(404,"请求地址不存在"),
    CODE_600(600,"请求参数错误"),
    CODE_601(601,"信息已经存在"),
    CODE_500(500,"服务器返回错误,请联系管理员");

    private Integer code;

    private String msg;

    ResponseCodeEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

封装一个统一的返回方法(正确,错误,异常)

java 复制代码
package com.example.demo.controller;

import com.example.demo.entity.enums.ResponseCodeEnum;
import com.example.demo.exception.BusinessException;
import com.example.demo.vo.ResponseVO;

public class ABaseController {
    protected static final String STATUS_SUCCESS = "success";

    protected static final String STATUS_ERROR = "error";

    protected <T> ResponseVO getSuccessResponseVO(T t){
        ResponseVO<T> responseVO = new ResponseVO<>();
        responseVO.setStatus(STATUS_SUCCESS);
        responseVO.setCode(ResponseCodeEnum.CODE_200.getCode());
        responseVO.setInfo(ResponseCodeEnum.CODE_200.getMsg());
        responseVO.setData(t);
        return responseVO;
    }

    protected <T> ResponseVO getBusinessErrorResponseVO(BusinessException e,T t){
        ResponseVO vo = new ResponseVO<>();
        vo.setStatus(STATUS_ERROR);
        if(e.getCode() == null){
            vo.setCode(ResponseCodeEnum.CODE_600.getCode());
        }else{
            vo.setCode(e.getCode());
        }

        vo.setInfo(e.getMessage());
        vo.setData(t);

        return vo;
    }

    protected <T> ResponseVO getServerErrorResponseVO(T t){
        ResponseVO vo = new ResponseVO<>();
        vo.setStatus(STATUS_ERROR);
        vo.setCode(ResponseCodeEnum.CODE_500.getCode());
        vo.setInfo(ResponseCodeEnum.CODE_500.getMsg());
        vo.setData(t);
        return vo;
    }

}

定义一个全局的异常处理器

java 复制代码
package com.example.demo.controller;


import com.example.demo.entity.enums.ResponseCodeEnum;
import com.example.demo.exception.BusinessException;
import com.example.demo.vo.ResponseVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
public class AGlobalExceptionHandlerController extends ABaseController {

    private static final Logger logger = LoggerFactory.getLogger(AGlobalExceptionHandlerController.class);

    @ExceptionHandler(value = Exception.class)
   public Object handleException(Exception e, HttpServletRequest request){
        logger.error("请求错误,请求地址{},错误信息:", request.getRequestURL(), e);
        ResponseVO ajaxResponse = new ResponseVO();
        //404
        if (e instanceof NoHandlerFoundException) {
            ajaxResponse.setCode(ResponseCodeEnum.CODE_404.getCode());
            ajaxResponse.setInfo(ResponseCodeEnum.CODE_404.getMsg());
            ajaxResponse.setStatus(STATUS_ERROR);
        } else if (e instanceof BusinessException) {
            //业务错误
            BusinessException biz = (BusinessException) e;
            ajaxResponse.setCode(biz.getCode() == null ? ResponseCodeEnum.CODE_600.getCode() : biz.getCode());
            ajaxResponse.setInfo(biz.getMessage());
            ajaxResponse.setStatus(STATUS_ERROR);
        } else if (e instanceof BindException || e instanceof MethodArgumentTypeMismatchException) {
            //参数类型错误
            ajaxResponse.setCode(ResponseCodeEnum.CODE_600.getCode());
            ajaxResponse.setInfo(ResponseCodeEnum.CODE_600.getMsg());
            ajaxResponse.setStatus(STATUS_ERROR);
        } else if (e instanceof DuplicateKeyException) {
            //主键冲突
            ajaxResponse.setCode(ResponseCodeEnum.CODE_601.getCode());
            ajaxResponse.setInfo(ResponseCodeEnum.CODE_601.getMsg());
            ajaxResponse.setStatus(STATUS_ERROR);
        } else {
            ajaxResponse.setCode(ResponseCodeEnum.CODE_500.getCode());
            ajaxResponse.setInfo(ResponseCodeEnum.CODE_500.getMsg());
            ajaxResponse.setStatus(STATUS_ERROR);
        }
        return ajaxResponse;
    }


}

最后进行测试

java 复制代码
package com.example.demo.controller;


import com.example.demo.entity.enums.ResponseCodeEnum;
import com.example.demo.exception.BusinessException;
import com.example.demo.vo.ResponseVO;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

@RestController
public class hello extends ABaseController {
    @RequestMapping("/hello")
    public void hello() {
        throw new BusinessException(ResponseCodeEnum.CODE_404);
    }
}

测试结果

相关推荐
我真的是大笨蛋3 小时前
K8S-Pod(下)
java·笔记·云原生·容器·kubernetes
碳水加碳水3 小时前
Java代码审计实战:XML外部实体注入(XXE)深度解析
java·安全·web安全·代码审计
努力也学不会java4 小时前
【设计模式】 原型模式
java·设计模式·原型模式
方渐鸿4 小时前
【2024】k8s集群 图文详细 部署安装使用(两万字)
java·运维·容器·kubernetes·k8s·运维开发·持续部署
学亮编程手记5 小时前
K8S v1.33 版本主要新特性介绍
java·容器·kubernetes
Haven-6 小时前
Java-面试八股文-JVM篇
java·jvm·面试
我真的是大笨蛋6 小时前
JVM调优总结
java·jvm·数据库·redis·缓存·性能优化·系统架构
wjs0406 小时前
Git常用的命令
java·git·gitlab
superlls6 小时前
(算法 哈希表)【LeetCode 349】两个数组的交集 思路笔记自留
java·数据结构·算法
田里的水稻7 小时前
C++_队列编码实例,从末端添加对象,同时把头部的对象剔除掉,中的队列长度为设置长度NUM_OBJ
java·c++·算法