spring boot的异常处理

目的:异常处理采用的是枚举型的  ExceptionEnum 枚举类  (特点 和别的公司的不太一样)

我们通常会把 事务 配置在 Service层,当数据库操作失败时让 Service 层抛出运行时异常,Spring 事物管理器就会进行回滚。如此一来,我们的 Controller 层就不得不进行 try-catch Service 层的异常,否则会返回一些不友好的错误信息到客户端。

    @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理

  • 优点:将 Controller 层的异常和数据校验的异常进行统一处理,减少模板代码,减少编码量,提升扩展性和可维护性。
  • 缺点:只能处理 Controller 层未捕获(往外抛)的异常,对于 Interceptor(拦截器)层的异常,Spring 框架层的异常,就无能为力了。

一、utils工具类


import com.lenovo.pcsd.bp.businesspartner.vo.ResultVO;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;

import java.util.List;

public class ResultVOUtil {

    public final static Integer ERROR_PARA = 4001;//参数错误
    private static final Integer ERROR_CODE_ID_NOT_FOUND = 40002;//对应ID未找到

    public static ResultVO errMap(Integer error, Object  str, Object object) {
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(error);
        resultVO.setMsg(str);
        resultVO.setData(object);
        return resultVO;
    }

    public static ResultVO success(Page pageresult) {

        PageUtil result = new PageUtil();
        BeanUtils.copyProperties(pageresult, result);
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(0);
        resultVO.setMsg("成功");
        resultVO.setData(result);
        return resultVO;
    }

    public static ResultVO success(Object object) {
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(0);
        resultVO.setMsg("成功");
        resultVO.setData(object);
        return resultVO;
    }
    public static ResultVO success() {
        return success(null);
    }

    public static ResultVO wrap(Object object, String msg) {
        ResultVO resultVO = null;
        if (object != null) {
            resultVO = ResultVOUtil.success(object);
        } else {
            resultVO = ResultVOUtil.error(msg);
        }
        return resultVO;
    }

    public static ResultVO wrap(Object source, Class type, String msg) {
        ResultVO resultVO = null;
        if (source != null) {

            resultVO = ResultVOUtil.success(source);
        } else {
            resultVO = ResultVOUtil.error(msg);
        }
        return resultVO;
    }




    public static ResultVO wrap(Page object, String msg) {
        ResultVO resultVO = null;
        if (object != null && object.getNumberOfElements() > 0) {
            resultVO = ResultVOUtil.success(object);
        } else {
            resultVO = ResultVOUtil.error(msg);
        }
        return resultVO;
    }


    public static ResultVO wrap(List list, String msg) {
        PageUtil pageUtil = new PageUtil(list);
        return wrap(pageUtil, msg);
    }

    public static ResultVO error(Integer code, String msg) {
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(code);
        resultVO.setMsg(msg);
        resultVO.setData(new String[]{});
        return resultVO;
    }

    public static ResultVO error(String msg) {
        return error(ERROR_CODE_ID_NOT_FOUND, msg);
    }

}

二、ResultVo vo类


//import lombok.Data;

import java.io.Serializable;

//@Data
public class ResultVO<T> implements Serializable {


    private static final long serialVersionUID = -8655891345041740105L;

    public ResultVO(){

    }

    public ResultVO(Integer error, T msg){
        this.code = error;
        this.msg = msg;
    }

    public ResultVO(Integer error, T msg, T data) {
        this.code = error;
        this.msg = msg;
        this.data = data;
    }
    /** 状态码. */
    private Integer code;

    /** 提示信息. */
    private T msg;

    /** 具体内容. */
    private T data;

    public Integer getCode() {
        return code;
    }

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

    public T getMsg() {
        return msg;
    }

    public void setMsg(T msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

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

三、AppcationException 类


import java.util.Optional;

public class AppcationException extends RuntimeException {

    private IBusinessRuntimeException iBusinessRuntimeException;
    private Integer stringcode;
    private String message;


    public AppcationException() {}

    //不需要传参数或者拼接的时候调用的构造方法
    public AppcationException(IBusinessRuntimeException iBusinessRuntimeException){
        this.iBusinessRuntimeException=iBusinessRuntimeException;
        this.stringcode=iBusinessRuntimeException.getCode();
        this.message=Optional.ofNullable(iBusinessRuntimeException.getMessage1()).orElse("");

    }

   //需要拼接时候调用的构造方法
    public AppcationException(IBusinessRuntimeException iBusinessRuntimeException,Object message1){
        this(iBusinessRuntimeException);
        this.message+=message1;
    }


    public IBusinessRuntimeException getiBusinessRuntimeException() {
        return iBusinessRuntimeException;
    }



    public Integer getCode() {
        return stringcode;
    }

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

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

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return super.toString();
    }
}

四、ExceptionEnum 枚举类  (特点 和别的公司的不太一样)

/**
 * 枚举类,用来存储自定义异常信息
 */
public enum ExceptionEnum implements  IBusinessRuntimeException{

    INSERTDATADEFEATED(1001,"数据插入失败,"),
    NOTFOUNTVALUE(1002,"找不到对应的值"),
    UPDATEDATADEFEAIED(1003,"更新数据失败"),
    DELETEDATADEFEAIED(1004,"删除数据失败"),
    TWOPARAMETERSDONTNULL(1005,"两个参数均不能为空"),
    PARAMETERDONTEMPTY(1006,"参数不能为空");


    private Integer stringcode;
    private String message1;


    ExceptionEnum(Integer code,String message1){
        this.stringcode=code;
        this.message1=message1;
    }

    @Override
    public Integer getCode() {
        return stringcode;
    }

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

    @Override
    public String getMessage1() {
        return message1;
    }

    public void setMessage1(String message1) {
        this.message1 = message1;
    }


}

五、IbusinessRuntimeException   接口类

public interface IBusinessRuntimeException {
     Integer getCode();
     String getMessage1();
}

六、异常处理类

/**
 *异常处理类
 */
@ControllerAdvice
@CommonsLog
public class GlobalExceptionHandler{


    @InitBinder
    public void initBinder(WebDataBinder binder) {}

    @ExceptionHandler(value = AppcationException.class)
    @ResponseBody
    public ResultVO handlerInvoiceException(AppcationException e){

        log.error("【业务异常】{}", e);
        return ResultVOUtil.error(e.getCode(),e.getMessage());
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultVO handlerException(Exception e){
        log.error("【系统异常】{}", e);
       /* return  ResultVOUtil.error(0,e.getMessage());*/
        return  ResultVOUtil.error(1,"未知异常,请联系管理员");
    }

    public static Logger getLogger() {
        return (Logger) log;
    }
}

代码详解

 @ExceptionHandler 注解声明异常处理方法

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    String handleException(){
        return "Exception Deal!";
    }
}

方法 handleException() 就会处理所有 Controller 层抛出的 Exception 及其子类的异常

Logger 进行所有的异常日志记录。

@ExceptionHandler(BusinessException.class) 声明了对 BusinessException 业务异常的处理,并获取该业务异常中的错误提示,构造后返回给客户端。

@ExceptionHandler(Exception.class) 声明了对 Exception 异常的处理,起到兜底作用,不管 Controller 层执行的代码出现了什么未能考虑到的异常,都返回统一的错误提示给客户端。

备注:以上 GlobalExceptionHandler 只是返回 Json 给客户端,更大的发挥空间需要按需求情况来做。


阅读更多

扫码向博主提问

javafanwk

非学,无以致疑;非问,无以广识
去开通我的Chat快问
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fwk19840301/article/details/80353652
文章标签: Exception
个人分类: Spring boot
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭