当前位置: 首页 > article >正文

如何使用SpringBoot处理全局异常

如何使用SpringBoot处理全局异常

使用@ControllerAdvice 和 @ExceptionHandler处理全局异常

参考:

@ControllerAdvice
@ResponseBody
@Slf4j
public class ExceptionHandler {


    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(value = {MissingServletRequestParameterException.class})
    public ViewResult<Object> missingServletRequestParameterException(MissingServletRequestParameterException e) {
        return ViewResult.state(RpcCode.OPERATION_NOT_PERMITTED_CODE, e.getMessage(), null);
    }

    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(value = {Exception.class})
    public ViewResult<Object> allException(Exception e) {
        ViewResult<Object> result = buildCustomException(e);
        if (result == null && e.getCause() != null) {
            result = buildCustomException(e.getCause() );
        }
        if (result != null) {
            return result;
        }
        // 请求传参等spring抛出的异常消息显示出来用于调试
        if (e instanceof ServletException || e instanceof NestedRuntimeException) {
            log.warn("", e);
            return ViewResult.state(RpcCode.SYSTEM_DEFAULT_ERROR_CODE, "请求错误:" + e.getMessage(), null);
        }
        log.error("system error:", e);
        return ViewResult.state(RpcCode.SYSTEM_DEFAULT_ERROR, null);
    }

    /**
     * 自定义异常的统一处理,各异常的message需要是汉字形式的提示文本。
     * @param e
     * @return
     */
    private ViewResult<Object> buildCustomException(Throwable e) {
        int code = RpcCode.SYSTEM_DEFAULT_ERROR_CODE;
        if (e instanceof NoAuthException) {
            code = RpcCode.OPERATION_NOT_PERMITTED_CODE;
        } else if (e instanceof com.chj.thor.auth.v2.exception.NoAuthException) {
            code = RpcCode.OPERATION_NOT_PERMITTED_CODE;
        } else if (e instanceof DuplicatedException) {
            code = RpcCode.RESOURCE_DUPLICATED_CODE;
        } else if (e instanceof NotFoundException) {
            code = RpcCode.RESOURCE_NOTFOUND_CODE;
        } else if (e instanceof OperationNotPermittedException) {
            code = RpcCode.OPERATION_NOT_PERMITTED_CODE;
        } else if (e instanceof ParamInvalidException) {
            code = ApiRpcCode.PARAM_INVALIDATED_CODE;
        } else if (e instanceof UrlUnreachableException) {
            code = ApiRpcCode.URL_UNREACHABLE_CODE;
        } else if (e instanceof ThirdServiceException) {
            code = ApiRpcCode.THIRD_SERVICE_CODE;
        } else if (e instanceof ThorException) {
            code = 500001;
        }
        if (code != RpcCode.SYSTEM_DEFAULT_ERROR_CODE) {
            return ViewResult.state(code, e.getMessage(), null);
        }
        return null;
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @org.springframework.web.bind.annotation.ExceptionHandler({
            MethodArgumentNotValidException.class,//requestBody校验
    })
    public ViewResult<Object> methodArgumentNotValidException(MethodArgumentNotValidException e) throws MethodArgumentNotValidException {
        log.info("[前置条件校验失败]", e);
        Class<?> clazz = e.getParameter().getExecutable().getDeclaringClass();
        //只有Controller层的参数出现问题才进行封装处理,否则直接上抛
        if (clazz.getSimpleName().endsWith("Controller")) {
            FieldError fieldError = e.getBindingResult().getFieldError();
            String message = "INVALID PARAMS";
            if (null != fieldError) {
                message += ":" + fieldError.getField();
                message += ":" + fieldError.getDefaultMessage();
            }
            return ViewResult.state(IRpcCode.ILLEGAL_ARGUMENT_CODE, message, null);
        } else {
            throw e;
        }
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @org.springframework.web.bind.annotation.ExceptionHandler({
            ConstraintViolationException.class //requestParam校验
    })
    public ViewResult<Object> constraintViolationException(ConstraintViolationException e) {
        log.info("[前置条件校验失败]", e);

        Set<ConstraintViolation<?>> validations = e.getConstraintViolations();
        StringBuilder message = new StringBuilder("INVALID PARAMS");
        //当配置的是failFast模式时,循环只会执行一遍
        for (ConstraintViolation<?> v : validations) {
            //只有Controller service层的参数出现问题才进行封装处理,否则直接上抛
            if (v.getRootBeanClass().getSimpleName().endsWith("Controller") ||
                    v.getRootBeanClass().getSimpleName().endsWith("ServiceImpl")) {
                message.append(":");
                message.append(v.getPropertyPath());
                message.append(":");
                message.append(v.getMessage());
            } else {
                throw e;
            }
        }
        return ViewResult.state(IRpcCode.ILLEGAL_ARGUMENT_CODE, message.toString(), null);
    }
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @org.springframework.web.bind.annotation.ExceptionHandler({
            HttpMessageNotReadableException.class, //requestParam校验
            HttpRequestMethodNotSupportedException.class,//method不支持
            HttpMediaTypeException.class,//ContentType问题
            ServletRequestBindingException.class//数据绑定问题
    })
    public ViewResult<Object> constraintViolationException(Exception e) {
        log.info("[客户端数据格式错误]", e);
        return ViewResult.state(IRpcCode.ILLEGAL_ARGUMENT_CODE, e.getMessage(), null);
    }



}



http://www.kler.cn/a/105960.html

相关文章:

  • 模式:每个服务一个数据库
  • Vue3中实现插槽使用
  • std::sort的底层原理(混合排序算法)
  • 解决Ubuntu18.04及以上版本高分辨率下导致字体过小问题
  • 河道无人机雷达测流监测系统由哪几部分组成?
  • 15分钟学 Go 第 59 天 :更高级的Go话题——接触微服务
  • MySQL不常用查询
  • Linux下的文件操作和文件管理
  • 微信小程序获取数据的方法——iBeacon蓝牙
  • Adversarial attacks and defenses on AI in medical imaging informatics: A survey
  • Easysearch 容量规划建议
  • OkHttp网络框架深入理解-SSL握手与加密
  • 雪糕冰淇淋经营配送小程序商城效果如何
  • 【Python机器学习】零基础掌握VotingClassifier集成学习
  • 在线设计数据库表用Itbuilder,极简易用真香!!!
  • 基于Jsp+Servlet+MySql的汉服网站的设计与实现-源码+毕业论文
  • 算法工程师-机器学习-数据科学家面试准备4-ML系统设计
  • git 版本管理
  • InterfaceWave 架构图
  • DSP 开发教程(0): 汇总
  • Python数据挖掘:入门、进阶与实用案例分析——基于非侵入式负荷检测与分解的电力数据挖掘
  • chrony参数及常用命令介绍
  • IDEA运行项目报错:Command line is too long的解决办法
  • 关于本地项目上传到gitee的详细流程
  • 自学(黑客技术)方法——网络安全
  • vantUI(Tabbar标签页)浏览器返回上一页的失效问题