Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 572|回复: 0

SpringMVC Controllrt 层的异常处理 (@ExceptionHandler)

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-9-2 15:11:37 | 显示全部楼层 |阅读模式

    SpringMVC Controllrt 层的异常处理 :

     一、统一的返回格式

      当我向前端返回数据时,无论是否成功,我都希望能提供一个统一的返回格式,和一个友善的错误提示。所以在完成异常处理前,先提供一个统一的返回格式CommonReturnType,它暂时含有两个字段

      status 表示上传数据成功或者失败,data  则是要 上传的数据。当成功上传数据时,status 为 “success ”,data 为 数据;当失败时 status 为 “fail”, data 为 错误的详细。

        private String status;
    
        private Object data;

      代码:

    package com.snapshot2.demo.response;
    
    /**
     * 通用的返回体,用于向前端返回一个通用的数据结构体
     */
    public class CommonReturnType {
        //表明返回的类型是"success " 或者 "fail"
        private String status;
        //若status = success data内放回前端需要的数据
        //若status = fail data内返回相应的错误信息
        private Object data;
    
        /* 两种创建方法 */
        /**
         * 当只传入数据data 时,默认成功
         * @param result
         * @return
         */
        public static CommonReturnType creat(Object result){
            return creat(result,"success");
        }
    
        /**
         * 当传入status 和 object 时使用这个创建方法
         * @param result
         * @param status
         * @return
         */
        public static CommonReturnType creat(Object result, String status){
            CommonReturnType commonReturnType = new CommonReturnType();
            commonReturnType.setData(result);
            commonReturnType.setStatus(status);
            return commonReturnType;
        }
    
        /* 省略 Getter and Setter */

      二、使用装饰器模式来自定义一个Controller 层的异常

        我们使用一个枚举来定义自己的一些异常类型,然后使用装饰器模式来实现对应的功能:

        UML 类设计图:

        

        代码实现:

       CommonErr:

     

    package com.snapshot2.demo.error;
    
    /**
     * 通用的异常接口,整合后端异常反馈给前端,使用装饰器模式
     * 这是装饰器的统一接口
     */
    public interface CommonError {
        public int getErrCode();
        public String getErrMsg();
        public CommonError setErrMsg(String errMsg);
    }

     

      CommonErrEnum:

    package com.snapshot2.demo.error;
    
    public enum CommonErrEnum implements CommonError {
    
        //00001 通用的参数不合法错误码
        PARAMTER_VALIDATION_ERROR(00001,"参数不合法"),
        UNKOWN_ERROR(00002,"未知错误"),
        //10000开头的错误码代表用户信息相关的错误
        USER_NOT_EXIST(100001,"用户不存在");
    
        private int errCode;
        private String errMsg;
        /* Constructor */
    
        CommonErrEnum(int errCode, String errMsg) {
            this.errCode = errCode;
            this.errMsg = errMsg;
        }
    
        @Override
        public int getErrCode() {
            return this.errCode;
        }
    
        @Override
        public String getErrMsg() {
            return this.errMsg;
        }
    
        @Override
        public CommonError setErrMsg(String errMsg) {
            this.errMsg = errMsg;
            return this;
        }
    }

      UserExceprion

    package com.snapshot2.demo.error;
    
    /**
     * 使用到了包装器模式
     */
    public class UserException extends Exception implements CommonError {
    
        //强关联一个CommonError(CommonErrorEnum)
        private CommonError commonError;
    
        //直接接受一个CommonEnum,用于构造一个业务异常
        public UserException(CommonError commonError){
            //调用Exception的初始化机制
            super();
            this.commonError = commonError;
        }
    
        /* Constructor */
        public UserException(CommonError commonError,String errMsg){
            super();
            this.commonError = commonError;
            this.commonError.setErrMsg(errMsg);
        }
    
        public void setCommonError(CommonError commonError) {
            this.commonError = commonError;
        }
    
    
        @Override
        public int getErrCode() {
            return this.commonError.getErrCode();
        }
    
        @Override
        public String getErrMsg() {
            return this.commonError.getErrMsg();
        }
    
        @Override
        public CommonError setErrMsg(String errMsg) {
            this.commonError.setErrMsg(errMsg);
            return this.commonError;
        }
    }

      我们可以看到,UserException 继承与Exception类,又实现了CommonErr接口。它关联了一个实现CommonErr接口的类(这里就是我们定义的Enum类),并且可以使用并增强它的方法。

      之后我们就可以在Controller层使用@ExceptionHandler(Exception.class) 注解来捕获在Controler层出现的Exception异常,并且消化它,向前端返回友善的错误提示:

        //定义ExceptionHandler解决Controller层未被处理掉的异常
        @ExceptionHandler(Exception.class)
        //Controller 层返回的异常应该属于后端的异常
        @ResponseStatus(HttpStatus.OK)
        @ResponseBody
        public Object handlerException(HttpServletRequest request, Exception e){
            Map<String,Object> responseData = new HashMap<>();
            CommonReturnType commonReturnType = new CommonReturnType();
            if(e instanceof UserException){
                //强制转化捕获的错误为UserException
                UserException userException = (UserException)e;
                //将错误信息转化为通用的上传格式
                commonReturnType.setStatus("fail");
                //将自定义的Exception 信息提取出来放在返回体中
                responseData.put("errCode",userException.getErrCode());
                responseData.put("errMsg",userException.getErrMsg());
                commonReturnType.setData(responseData);
            } else{
                responseData.put("errCode",CommonErrEnum.UNKOWN_ERROR.getErrCode());
                responseData.put("errMsg",CommonErrEnum.UNKOWN_ERROR.getErrMsg());
                commonReturnType.setStatus("fail");
                commonReturnType.setData(responseData);
            }
            return commonReturnType;
    
        }

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 19:55 , Processed in 0.112819 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表