Bootstrap

java中全局异常捕捉

java中全局异常捕捉

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public BaseOutDTO defaultErrorHandler(HttpServletRequest req, Exception e) {
        log.error("interface {} process fail", req.getRequestURI());
        log.error("exception info: ", e);
        return new BaseOutDTO().fail(new BaseError().nextCodeError("系统繁忙"));
    }

    /**
     * 非法json异常
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    public BaseOutDTO HttpMessageNotReadableExceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {
        log.error("interface {} process fail for error: \n{}", req.getRequestURI(), e.toString());
        log.debug("exception info", e);
        return new BaseOutDTO().fail(new BaseError("非法的JSON参数"));
    }

    /**
     * 请求方法错误
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public BaseOutDTO HttpRequestMethodNotSupportedExceptionHandler(HttpServletRequest req, HttpRequestMethodNotSupportedException e) {
        log.error("interface {} process fail for error: \n{}", req.getRequestURI(), e.toString());
        log.debug("exception info", e);
        return new BaseOutDTO().fail(new BaseError("不支持的请求调用"));
    }

    /**
     * 处理 SpringMVC 参数校验不正确
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public BaseOutDTO methodArgumentNotValidExceptionExceptionHandler(MethodArgumentNotValidException ex) {
        log.warn("[methodArgumentNotValidExceptionExceptionHandler]");
        FieldError fieldError = ex.getBindingResult().getFieldError();
        return new BaseOutDTO().fail(new BaseError().nextCodeError(String.format("请求参数不正确:%s", fieldError.getDefaultMessage())));
    }

    /**
     * 处理 SpringMVC 参数绑定不正确,本质上也是通过 Validator 校验
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public BaseOutDTO bindExceptionHandler(BindException ex) {
        log.warn("[handleBindException]");
        FieldError fieldError = ex.getFieldError();
        return new BaseOutDTO().fail(new BaseError().nextCodeError(String.format("请求参数不正确:%s", fieldError.getDefaultMessage())));
    }

    @ExceptionHandler(value = BaseException.class)
    @ResponseBody
    public BaseOutDTO knownErrorHandler(HttpServletRequest req, BaseException e) {
        log.error("interface {} process fail for error : {}", req.getRequestURI(), e.getError().getMsg());
        log.debug("exception info", e);
        return new BaseOutDTO().fail(e.getError());
    }


    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public BaseOutDTO handleMethodArgumentTypeMismatch(MethodArgumentTypeMismatchException ex) {
        String error = "参数'" + ex.getName() + "'应该是'" + ex.getRequiredType().getSimpleName() + "'类型";
        return new BaseOutDTO().fail(new BaseError(error));
    }
}

2.BaseOutDTO类

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
public class BaseOutDTO implements Serializable, Cloneable {

    private static final int SUCCESS_CODE = 0;
    private int code = SUCCESS_CODE;
    private String msg = "成功";
    private Object data;

    public BaseOutDTO(String msg) {
        this.msg = msg;
    }

    public BaseOutDTO fail(int code, String msg) {
        this.code = code;
        this.msg = msg;
        return this;
    }

    public BaseOutDTO fail(BaseError baseError) {
        this.code = baseError.getCode();
        this.msg = baseError.getMsg();
        return this;
    }

    public static BaseOutDTO success(Object data) {
        BaseOutDTO out = new BaseOutDTO();
        out.setData(data);
        return out;
    }

    public static BaseOutDTO success() {
        return new BaseOutDTO();
    }

    @JsonIgnore
    public boolean isSuccess() {
        return this.code == SUCCESS_CODE;
    }

    @Override
    public BaseOutDTO clone() {
        try {
            return (BaseOutDTO) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

3.BaseError

package com.base.exception;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class BaseError {

    public BaseError(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    /**
     * 默认错误码的构造
     */
    public BaseError(String msg) {
        this.code = 100;
        this.msg = msg;
    }

    public static final int SYS_ERR_CODE_START = 10000;

    private int internalCode = 1000;
    private int code;
    private String msg;
    
    public BaseError nextCodeError(String msg) {
        internalCode++;
        code = internalCode;
        this.msg = msg;
        return this;
    }
}

4.BaseException

package com.base.exception;

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

/**
 * 异常处理
 */
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class BaseException extends RuntimeException {
    private BaseError error;
    protected Throwable throwable;

    public BaseException(BaseError error) {
        super(error.getMsg());
        this.error = error;
    }

    public static BaseException failure(String errorMsg) {
        return new BaseException(new BaseError().nextCodeError(errorMsg));
    }

    public static BaseException failure(int code, String errorMsg) {
        return new BaseException(new BaseError(code, errorMsg));
    }
}

;