zoukankan      html  css  js  c++  java
  • 项目使用 GlobalExceptionHandler 与 @RestControllerAdvice自定义异常 二

    未经博主允许不得转载:

      自定义异常,不仅需要定义符合自己业务的异常状态码,也需要定义自己项目中的异常封装。记录下自己手敲代码中的异常封装:

    1.定义一个枚举类,枚举类中定义状态码及状态码描述,再定义一个接口,使枚举类实现该接口,从而可以获取枚举类中当前的异常状态码,异常描述等。

    package com.lf.mp.test;
    
    /**
     * 用来获取异常的状态码及描述
     */
    public interface ExceptionType {
        // 获取描述
        public String getMessage();
    
        // 获取状态码
        public Integer getCode();
    
        // 是否参数化
        public Boolean isParam();
    }
    package com.lf.mp.test;
    
    /**
     * 自定义异常枚举
     */
    public enum ExceptionEnum implements ExceptionType {
        NOT_FOUNT(404, "页面或路径不存在"),
    
        METHOD_NOT_ALLOWED(405, "方法不允许", true),
    
        USEER_NOT_EXISTED(100001, "用户不存在"),
    
        PARAM_ERROR(100002, "参数错误", true),
    
        // 对于参数使用异常这种场景,会对参数进行不同的描述,这里可使用{}的方式代替,在解析的时候对{}进行替换
        PARAMS_ERROR(100002, "{}"),;
        // 状态码
        private Integer code;
        // 状态码描述
        private String message;
        // 是否参数解析
        private boolean isParam;
    
        // 重载
        ExceptionEnum(Integer code, String message, boolean isParam) {
            this.code = code;
            this.message = message;
            this.isParam = isParam;
        }
    
        // 重载
        ExceptionEnum(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    
        @Override
        public String getMessage() {
            this.message = message;
            return message;
        }
    
        @Override
        public Integer getCode() {
            return this.code;
        }
    
        @Override
        public Boolean isParam() {
            return this.isParam;
        }
    }

    2.自定义异常类;

    package com.lf.mp.test;
    
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * 自定义业务异常
     */
    @Data
    public class CustomException extends RuntimeException implements Serializable {
        private static final long serialVersion = 493083738120393040L;
        private ExceptionEnum exceptionEnum;
        private Integer code;
        private String message;
    
        // 对自定义异常进行构造封装
        public CustomException(ExceptionEnum exceptionEnum) {
            this.exceptionEnum = exceptionEnum;
            this.message = exceptionEnum.getMessage();
            this.code = exceptionEnum.getCode();
        }
    
        public CustomException(String message, ExceptionEnum exceptionEnum) {
            super(message);
            this.exceptionEnum = exceptionEnum;
            this.message = message;
        }
    
        public CustomException(Throwable cause, ExceptionEnum exceptionEnum) {
            this.exceptionEnum = exceptionEnum;
            this.message = cause.getMessage();
        }
    
    }

    3.自定义异常捕捉后返回的数据接口

    package com.lf.mp.test;
    
    import lombok.Data;
    
    /**
     * 定义response响应数据体
     */
    @Data
    public class Result {
        // 状态码
        private Integer code;
        // 响应描述
        private String msg;
        // 响应数据
        private Object data;
    
        public Result(Integer code, String msg) {
            this.code = code;
            this.msg = msg;
        }
    }

    4.通过@ControllerAdvice 或 @RestControllerAdvice 注解封装项目中的异常

      通过@ControllerAdvice ,可以将对于控制器的全局配置放置在同一个位置,注解了@Controller 的类的方法可以使用@ExceptionHandler,@InitBinder,@ModelAttribute注解

    到方法上,这对所有注解了@RequestMapping 的控制器内的方法有效。

      @ExceptionHandler:用于全局处理控制器里的异常

      @InitBinder: 用来设置WebDataBinder,WebDataBinder 用来自动绑定前台请求参数到Model中

      @ModelAttribute:绑定键值对到Model里,此处是让全局的@RequestMapping 都能获得在此处设置的键值对。

            

      @RestControllerAdvice 则是@ControllerAdvice 与 @ResponseBody 的合体

           @ResponseBody 支持将返回值放在response 体内,而不是返回一个页面。我们在很多基于ajax 的程序的时候,可以一次注解返回数据而不是页面。

    package com.lf.mp.test;
    
    import org.springframework.http.HttpStatus;
    import org.springframework.validation.BindException;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 全局异常处理器
     */
    @RestControllerAdvice
    public class GlobalExceptionHandler {
        //处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
        @ExceptionHandler(BindException.class)
        public Result BindExceptionHandler(BindException e) {
            return new Result(ExceptionEnum.METHOD_NOT_ALLOWED.getCode(), e.getMessage());
        }
    
        @ExceptionHandler(CustomException.class)
        public Result customExceptionHandler(HttpServletRequest request, final CustomException exception, HttpServletResponse response) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            return new Result(exception.getCode(), exception.getMessage());
        }
    
        @ExceptionHandler(MethodArgumentNotValidException.class)
        public Result MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException exception) {
            return new Result(ExceptionEnum.METHOD_NOT_ALLOWED.getCode(), exception.getMessage());
        }
    
    
    }

    使用示例如下:

        private void test() {
            try {
                int a = 1/0;
            } catch (CustomException e) {
                throw new CustomException(ExceptionEnum.OTHER_ERROR,"计算异常");
            }
        }

    -----

    这种异常的封装很简洁,也很好使用,对项目的异常状态码,异常描述都有较好的封装。使用也很方便。

    还有一种经常使用的异常封装。定义一个CustomException,并继承Exception类,在CustomException中定义异常状态码,以描述两个属性,

    在使用过程中,状态码则使用HttpStatus中的异常码,描述则使用自定义描述,也很方便,主要符合自己业务,方便开发即可。

  • 相关阅读:
    10月1日学习日志
    RK987三模键盘使用说明书
    信封中装有10张奖券,只有一张有奖,从信封中每次抽取1张奖券后放回,如此重复抽取n次,中奖的概率为P,求P的表达式。
    SAP自动过账的概念
    SAP内部订单使用
    SAP凭证日期,过账日期的区别
    SAP增强
    金融财团控制全球经济的四种武器
    联想ZUI应用图标自动排序
    SAPFICO基础(1)
  • 原文地址:https://www.cnblogs.com/zjdxr-up/p/14054446.html
Copyright © 2011-2022 走看看