spring boot 实现全局异常处理

1.前言

在我们实际项目开放中经常需要我们处理很多的异常,如何在spring boot 项目里面实现全局异常呢?今天我们就来聊聊。

2.用到注解

@RestControllerAdvice 和 @ExceptionHandler

@RestControllerAdvice
@RestControllerAdvice是@ControllerAdvice的派生注解,它继承了@ResponseBody,说明了它是一个@Controller的增强器,并且会把信息通过response body响应给前端。

我们可以通过它来拦截spring 的全局异常,例:

@RestControllerAdvice(annotations = {RestController.class, Service.class, Component.class})

通过上面的代码,我们可以看出它会拦截 含有 @RestController,@Service,@Component这些注解类的异常,说白了定义@RestControllerAdvice的类就是一个控制器,可以去拦截符合要求类的异常。

@ExceptionHandler
@ExceptionHandler 作用是拦截和处理具体的某个异常

3.程序实现

3.1 自定义异常类

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@NoArgsConstructor
public class ValidateException extends RuntimeException {
    private static final long serialVersionUID = 8641717992917473974L;
    private int errorCode;

    private String errorMag;

    public ValidateException(int errorCode, String errorMag) {
        super(errorMag);
        this.errorCode = errorCode;
        this.errorMag = errorMag;
    }
}

3.2 定义抛出异常工具类


import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.Collection;

@Setter
@Getter
@NoArgsConstructor
public class ErrorFormatable {
    private int errorCode;

    private String errorMsg;

    public ErrorFormatable(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public ValidateException baseException(String errorMsg) {
        return new ValidateException(this.errorCode, String.format(this.errorMsg, errorMsg));
    }

    public void isEmptyThrow(Object o, String msg) {
        if (o == null) {
            throw baseException(msg);
        }
    }

    public void isNotEmptyThrow(Object o, String msg) {
        if (o != null) {
            throw baseException(msg);
        }
    }

    public void isEmptyThrow(Long o, String msg) {
        if (o == null || o == 0L) {
            throw baseException(msg);
        }
    }

    public void isNotEmptyThrow(Long o, String msg) {
        if (o != null && o != 0L) {
            throw baseException(msg);
        }
    }

    public void isNotEmptyThrow(Collection collection, String msg) {
        if (!CollectionUtils.isEmpty(collection)) {
            throw baseException(msg);
        }
    }

    public void isEmptyThrow(Collection collection, String msg) {
        if (CollectionUtils.isEmpty(collection)) {
            throw baseException(msg);
        }
    }

    public void isEmptyThrow(Integer o, String msg) {
        if (o == null || o == 0) {
            throw baseException(msg);
        }
    }

    public void isNotEmptyThrow(Integer o, String msg) {
        if (o != null && o != 0) {
            throw baseException(msg);
        }
    }

    public void isEmptyThrow(String o, String msg) {
        if (StringUtils.isBlank(o)) {
            throw baseException(msg);
        }
    }

    public void isNotEmptyThrow(String o, String msg) {
        if (StringUtils.isNotBlank(o)) {
            throw baseException(msg);
        }
    }

    public void assemble(Boolean throwable, String msg) {
        if (throwable) {
            throw baseException(msg);
        }
    }

    public static final int SUCCESS_CODE = 1000;
    public static final String SUCCESS_MSG = "操作成功";
    public static final ErrorFormatable NOT_EMPTY = new ErrorFormatable(1001, "%s不能为空");
    public static final ErrorFormatable NEED_EMPTY = new ErrorFormatable(1002, "%s必须为空");
    public static final ErrorFormatable NOT_EXIST = new ErrorFormatable(1010, "%s不存在");
    public static final ErrorFormatable EXIST = new ErrorFormatable(1004, "%s已经存在");
    public static final ErrorFormatable CUSTOM = new ErrorFormatable(1005, "%s");
    public static final ErrorFormatable INTERNAL_ERROR = new ErrorFormatable(1009, "%s");
    public static final int VALIDATE_FAIL_CODE = 1007;
    public static final int INTERVAL_FAIL_CODE = 1006;
    public static final int AUTHORIZATION_FAIL_CODE = 1008;
    public static final int AUTHENTICATION_FAIL_CODE = 1009;
}

3.3 定义前端返回类

import com.fasterxml.jackson.annotation.JsonProperty;
import com.flow.errors.ErrorFormatable;
import com.flow.errors.ValidateException;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

@Setter
@Getter
public class ServerResponse implements Serializable {
    private static final long serialVersionUID = 5880424035498593065L;
    private int errorCode;

    private String errorMsg;

    @JsonProperty
    public Boolean success() {
        return this.errorCode == ErrorFormatable.SUCCESS_CODE;
    }

    public ServerResponse(){
        this(ErrorFormatable.SUCCESS_CODE, ErrorFormatable.SUCCESS_MSG);
    }

    public ServerResponse(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public ServerResponse(ValidateException e) {
        this.errorCode = e.getErrorCode();
        this.errorMsg = e.getErrorMag();
    }

    public ServerResponse(String errorMsg) {
        this(ErrorFormatable.SUCCESS_CODE, errorMsg);
    }
}

3.4 定义拦截异常类

import com.flow.errors.ErrorFormatable;
import com.flow.errors.ValidateException;
import com.flow.responses.ServerResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;

@RestControllerAdvice(annotations = {RestController.class, Service.class, Component.class})
@Slf4j
public class ResponseHandler {
    @ExceptionHandler(value = RuntimeException.class)
    public ServerResponse runTime(RuntimeException e) {
        log.error("运行时异常", e);
        return new ServerResponse(ErrorFormatable.INTERVAL_FAIL_CODE, e.getLocalizedMessage());
    }
    @ExceptionHandler(value = ValidateException.class)
    public ServerResponse validateHandler(ValidateException e) {
        log.error("系统异常", e);
        return new ServerResponse(e.getErrorCode(), e.getErrorMag());
    }

    @ExceptionHandler(value = IOException.class)
    public ServerResponse ioException(IOException e) {
        log.error("系统异常", e);
        return new ServerResponse(ErrorFormatable.INTERVAL_FAIL_CODE, e.getLocalizedMessage());
    }
}

你可能感兴趣的:(#,spring,boot,spring,boot,spring)