SpringBoot中使用RestControllerAdvice进行统一异常拦截

1、创建一个ApiExceptionHandler类,定义全局异常捕捉处理

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.zongjikeji.core.result.Result;
import com.zongjikeji.core.result.ResultEnum;

/**
 * @author Nick Tan
 */@RestControllerAdvice
public class ApiExceptionHandler {

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

    @ExceptionHandler(ErrorException.class)
    public Result errorExceptionHandler(ErrorException ex, HttpServletRequest request) {
        // response.setStatus(ex);
        return resultFormat(ex.getCode(), ex.getMessage(), ex, request);
    }

    @ExceptionHandler(RuntimeException.class)
    public Result runtimeExceptionHandler(RuntimeException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler(NullPointerException.class)
    public Result nullPointerExceptionHandler(NullPointerException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler(ClassCastException.class)
    public Result classCastExceptionHandler(ClassCastException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler(IOException.class)
    public Result iOExceptionHandler(IOException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler(NoSuchMethodException.class)
    public Result noSuchMethodExceptionHandler(NoSuchMethodException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler(IndexOutOfBoundsException.class)
    public Result indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler({ HttpMessageNotReadableException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result requestNotReadable(HttpMessageNotReadableException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.PARAM_ERROR, ex, request);
    }

    @ExceptionHandler({ TypeMismatchException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result requestTypeMismatch(TypeMismatchException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.PARAM_ERROR, ex, request);
    }

    @ExceptionHandler({ MissingServletRequestParameterException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result requestMissingServletRequest(MissingServletRequestParameterException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.PARAM_ERROR, ex, request);
    }

    @ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public Result request405(HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.METHOD_NOT_ALLOWED, ex, request);
    }

    @ExceptionHandler({ HttpMediaTypeNotAcceptableException.class })
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public Result request406(HttpMediaTypeNotAcceptableException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.NOT_ACCEPTABLE, ex, request);
    }

    @ExceptionHandler({ ConversionNotSupportedException.class, HttpMessageNotWritableException.class })
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result server500(RuntimeException ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.INTERNAL_SERVER_ERROR, ex, request);
    }

    @ExceptionHandler({ StackOverflowError.class })
    public Result requestStackOverflow(StackOverflowError ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    @ExceptionHandler({ Exception.class })
    public Result exception(Exception ex, HttpServletRequest request) {
        return resultFormat(ResultEnum.UNKNOW_ERROR, ex, request);
    }

    private <T extends Throwable> Result resultFormat(int code, String message, T ex, HttpServletRequest request) {
        logger.warn("Controller Exception[" + request.getRequestURI() + "]-" + code + ":" + message, ex);
        return Result.instance(code, message, null);
    }

    private <T extends Throwable> Result resultFormat(ResultEnum ResultEnum, T ex, HttpServletRequest request) {
        logger.warn("Controller Exception[" + request.getRequestURI() + "]-" + ResultEnum.getCode() + ":"
                + ResultEnum.getMessage(), ex);
        return Result.instance(ResultEnum.getCode(), ResultEnum.getMessage(), null);
    }
}

2、创建一个ErrorException自定义异常类

/**
 * @author Nick Tan
 */public class ErrorException extends RuntimeException {

    private static final long serialVersionUID = -1162371143658279115L;

    private int code;

    private String message;

    public ErrorException(int code, String message) {
        super();
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

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

3、返回数据及错误代码

参考:Java API统一返回Response格式

发表评论