全局异常拦截 统一返回模式 自定义异常

文章目录

    • 全局的异常拦截器
    • 自定义异常
    • 统一修改返回方式

全局的异常拦截器

package 
com.bsj.obd.config.exception;


import com.bsj.consumerQ.Until.ExceptionUntil;
import com.bsj.obd.global.JsonResult;
import com.bsj.obd.global.JsonResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
 *
 */
@Slf4j
@RestControllerAdvice
@Order(-1)
public class GlobalExceptionHandler {
    private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: requestUrl: %s Code: %s Detail: %s";

    /**
     * 参数校验返回
     *
     * @param ex
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = BindException.class)
    public JsonResult bindExceptionErrorHandler(BindException ex) {
        log.error("bindExceptionErrorHandler info:{}", ex.getMessage());
        StringBuilder sb = new StringBuilder();
        FieldError fieldError = ex.getFieldError();
        sb.append(fieldError.getDefaultMessage());
        return new JsonResult(JsonResultEnum.PARAM_ERROR.getCode(), sb.toString());
    }

    /**
     * 自定义异常返回
     *
     * @param apiException
     * @return
     */
    @ExceptionHandler(ApiException.class)
    public JsonResult handFaceException(ApiException apiException) {
        JsonResultEnum status = apiException.getStatus();
        return new JsonResult(status, apiException.getMessage());
    }

    /**
     * 其他错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({Exception.class})
    public JsonResult exception(HttpServletRequest request, Exception ex) {
        return resultFormat(request, JsonResultEnum.EXCEPTION, ex);
    }

    /**
     * 运行时异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public JsonResult runtimeExceptionHandler(HttpServletRequest request, RuntimeException ex) {
        return resultFormat(request, JsonResultEnum.RUNTIME_EXCEPTION, ex);
    }

    /**
     * 空指针异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    public JsonResult nullPointerExceptionHandler(HttpServletRequest request, NullPointerException ex) {
        return resultFormat(request, JsonResultEnum.NPE, ex);
    }

    /**
     * 类型转换异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(ClassCastException.class)
    public JsonResult classCastExceptionHandler(HttpServletRequest request, ClassCastException ex) {
        return resultFormat(request, JsonResultEnum.CLASS_CAST_EXCEPTION, ex);
    }

    /**
     * IO异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(IOException.class)
    public JsonResult iOExceptionHandler(HttpServletRequest request, IOException ex) {
        return resultFormat(request, JsonResultEnum.IO_EXCEPTION, ex);
    }

    /**
     * 未知方法异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(NoSuchMethodException.class)
    public JsonResult noSuchMethodExceptionHandler(HttpServletRequest request, NoSuchMethodException ex) {
        return resultFormat(request, JsonResultEnum.NO_SUCH_METHOD_EXCEPTION, ex);
    }

    /**
     * 数组越界异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public JsonResult indexOutOfBoundsExceptionHandler(HttpServletRequest request, IndexOutOfBoundsException ex) {
        return resultFormat(request, JsonResultEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION, ex);
    }

    /**
     * 400错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public JsonResult requestNotReadable(HttpServletRequest request, HttpMessageNotReadableException ex) {
        System.out.println("400..requestNotReadable");
        return resultFormat(request, JsonResultEnum.HTTP_MESSAGE_NOT_READABLE_EXCEPTION, ex);
    }

    /**
     * 400错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({TypeMismatchException.class})
    public JsonResult requestTypeMismatch(HttpServletRequest request, TypeMismatchException ex) {
        System.out.println("400..TypeMismatchException");
        return resultFormat(request, JsonResultEnum.Type_MISMATCH_EXCEPTION, ex);
    }

    /**
     * 400错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public JsonResult requestMissingServletRequest(HttpServletRequest request, MissingServletRequestParameterException ex) {
        System.out.println("400..MissingServletRequest");
        return resultFormat(request, JsonResultEnum.MISSING_SERVLET_REQUEST_PARAMETER_EXCEPTION, ex);
    }

    /**
     * 405错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public JsonResult request405(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) {
        return resultFormat(request, JsonResultEnum.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION, ex);
    }


    /**
     * 500错误
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public JsonResult server500(HttpServletRequest request, RuntimeException ex) {
        System.out.println("500...");
        return resultFormat(request, JsonResultEnum.FAIL_SERVER, ex);
    }

    /**
     * 栈溢出
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({StackOverflowError.class})
    public JsonResult requestStackOverflow(HttpServletRequest request, StackOverflowError ex) {
        return resultFormat(request, JsonResultEnum.SOE, ex);
    }

    private <T extends Throwable> JsonResult resultFormat(HttpServletRequest request, JsonResultEnum jsonResultEnum, T ex) {
        ex.printStackTrace();
        log.error("@@@服务异常" + String.format(logExceptionFormat, request.getRequestURL(), jsonResultEnum, ExceptionUntil.getErrorStr(ex)));
        return new JsonResult(JsonResultEnum.EXCEPTION);
    }

}

自定义异常

package com.bsj.obd.config.exception;


import com.bsj.obd.global.JsonResultEnum;

public class ApiException extends RuntimeException {
//利用枚举来统一规范返回语句,利于后期的海外版扩展
//public enum JsonResultEnum {
//
//    SUCCESS(0, "请求成功"),
//    FAIL(-1, "请求失败"),
//    PARAM_ERROR(-2, "参数错误"),
//;
//    private Integer code;
//    private String msg;
//
//    JsonResultEnum(Integer code, String message) {
//        this.code = code;
//        this.msg = message;
//    }
//
//    public Integer getCode() {
//        return code;
//    }
//
//    public String getMsg() {
//        return msg;
//    }
//
//    public void setMsg(String msg) {
//        this.msg = msg;
 //   }
//}
 //   private JsonResultEnum status;
//
//
//    public ApiException(JsonResultEnum status) {
//        this.status = status;
//    }


    public ApiException(JsonResultEnum status, String message) {
        super(message);
//        Assert.notNull(message, "message cant't be null");
//        自定义异常提示
//    public static void main(String[] args) {
//        getaVoid();
//        System.out.println("hello");
//    }
//
//    private static void getaVoid() {
//        Assert.notNull(null, "Source must not be null");
//    }
//        Assert.notNull(status, "status cant't be null");
        status.setMsg(message);
        this.status = status;

    }

    public ApiException(JsonResultEnum status, String message, Throwable cause) {
        super(message, cause);
//        Assert.notNull(message, "message cant't be null");
//        Assert.notNull(status, "status cant't be null");
        this.status = status;
    }

//这个才是自定义的正则返回,方法在全局异常拦截哪里
    public JsonResultEnum getStatus() {
        return status;
    }
}

统一修改返回方式

确定之一就是:如果只单单返回String的话是会报转换类型错误,因为String不是基本类型,List就可以转换成功

package com.bsj.obd.config.advice;

import com.bsj.obd.global.JsonResult;
import com.bsj.obd.global.PageJsonResult;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 统一修改api的成功返回值
 */
 //表示在com.bsj.obd.web这个包里面的所有返回都进行修改
@RestControllerAdvice(basePackages = {"com.bsj.obd.web"})
public class ApiControllerAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (!(body instanceof JsonResult) && !(body instanceof PageJsonResult)) {
            return JsonResult.success(body);
        }

        return body;
    }

}

你可能感兴趣的:(全局异常拦截 统一返回模式 自定义异常)