zoukankan      html  css  js  c++  java
  • 全局异常捕获处理-@ControllerAdvice+@HandleException

    涂涂影院管理系统这个demo中有个异常管理的标签,用于捕获 涂涂影院APP用户异常信息 ,有小伙伴好奇,排除APP,后台端的是如何处理全局异常的,故项目中的实际应用已记之。

    关于目前的异常处理

    在使用全局异常处理之前,就目前我们是如何处理程序中的异常信息的呢?

    throws Exception + try-catch

    怎么讲?

    在我们目前项目中,往往事务发生在 Service 层,因为会牵扯到调用 Dao 跟数据库打交道,当数据库操作失败时,会让 Service 层抛出运行时异常,Spring 事物管理器就会进行回滚。

    Service 抛出异常,那么 Controller 必然要去捕获,处理异常,所以,try-catch 就出现了。

    看一下Service:

    public interface ServiceI{
        ## 保存实体的方法
        public Serializable save(Entity entity) throws Exception;
    }

    看一下Controller的某个调用方法:

    @PostMapping(value = "")
    public AppResponse add(@RequestBody Entity entity, Errors errors){
        AppResponse resp = new AppResponse();
        try {
            Entity endity = new Entity();
            endity.setXxx();

            ServiceI.save(dog);

            ## 返回数据
            resp.setData(newDog);

        }catch (BusinessException e){
            resp.setFail(e.getMessage());
        }catch (Exception e){
            resp.setFail("操作失败!");
        }
        return resp;
    }

    看上去也没什么别就,但是一个类中出现大面积的 try-catch ,就显得非常难看且冗余。

    如果使用 @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理,只要设计得当,就再也不用在 Controller 层进行 try-catch 了。

    书写全局异常处理

    1. @ControllerAdvice注解

    定义全局异常处理类,@RestControllerAdvice 为 @ResponseBody + @ControllerAdvice

    @Slf4j
    @RestControllerAdvice
    public class RestCtrlExceptionHandler {

    }
    2. @ExceptionHandler注解

    声明异常处理方法,方法 handleException() 就会处理所有 Controller 层抛出的 Exception 及其子类的异常,这是最基本的用法了。

        @ExceptionHandler(Exception.class)
        @ResponseStatus(value = HttpStatus.OK)
        public Result<Object> handleException(Exception e) {

            String errorMsg = "Exception";
            if (e!=null){
                errorMsg = e.getMessage();
                log.error(e.toString());
            }
            return new ResultUtil<>().setErrorMsg(500, errorMsg);
        }

    结合上边1、2组合一下:

    @Slf4j
    @RestControllerAdvice
    public class RestCtrlExceptionHandler {

        @ExceptionHandler(TmaxException.class)
        @ResponseStatus(value = HttpStatus.OK)
        public Result<Object> handleXCloudException(TmaxException e) {

            String errorMsg = "Tmax exception";
            if (e!=null){
                errorMsg = e.getMsg();
                log.error(e.toString());
            }
            return new ResultUtil<>().setErrorMsg(500, errorMsg);
        }

        @ExceptionHandler(Exception.class)
        @ResponseStatus(value = HttpStatus.OK)
        public Result<Object> handleException(Exception e) {

            String errorMsg = "Exception";
            if (e!=null){
                errorMsg = e.getMessage();
                log.error(e.toString());
            }
            return new ResultUtil<>().setErrorMsg(500, errorMsg);
        }
    }

    看一下 handleXCloudException() 方法

    通常我们需要抛出我们自定义异常,而不是一有异常就全部进入 handleException 中,该方法中 TmaxException 即为我们自定义的异常。

    @Data
    public class TmaxException extends RuntimeException {

        private String msg;

        public TmaxException(String msg){
            super(msg);
            this.msg = msg;
        }
    }

    这样,我们就可以在 Controller 中抛出我们定义的异常了,比如:

    throw new TmaxException("连接ES失败,请检查ES运行状态");

    如果文章有错的地方欢迎指正,大家互相留言交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:niceyoo

  • 相关阅读:
    Path Sum
    Intersection of Two Linked Lists (求两个单链表的相交结点)
    Nginx入门资料
    赛马问题
    翻转单词顺序 VS 左旋转字符串
    重建二叉树
    Fibonacci相关问题
    Find Minimum in Rotated Sorted Array(旋转数组的最小数字)
    常用查找算法总结
    Contains Duplicate
  • 原文地址:https://www.cnblogs.com/niceyoo/p/10913851.html
Copyright © 2011-2022 走看看