IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring复习——day16_SpringMVC_异常处理器 -> 正文阅读

[Java知识库]Spring复习——day16_SpringMVC_异常处理器

目录

?

11、异常处理器

11.1、异常处理器简单入门

11.1.1、基于配置的异常处理

11.1.2、基于注解的异常处理

11.2、异常处理器的使用

11.2.1、创建异常处理器类

11.2.2、让程序抛出异常

11.2.3、运行程序,测试

11.3、项目异常处理方案

11.3.1、异常分类

11.3.2、异常解决方案

11.3.3、异常解决方案的具体实现

11.3.4、小结:


11、异常处理器

11.1、异常处理器简单入门

11.1.1、基于配置的异常处理

SpringMVC提供了一个处理器控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver

HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver

SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver,使用方式:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
        <!--
            properties的键表示处理器方法执行过程中出现的异常
            properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
        -->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <!--
        exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享
    -->
    <property name="exceptionAttribute" value="ex"></property>
</bean>

11.1.2、基于注解的异常处理

//@ControllerAdvice将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController {

    //@ExceptionHandler用于设置所标识方法处理的异常
    @ExceptionHandler(ArithmeticException.class)

    //ex表示当前请求处理中出现的异常对象
    public String handleArithmeticException(Exception ex, Model model){
        model.addAttribute("ex", ex);
        return "error";
    }
}

11.2、异常处理器的使用

11.2.1、创建异常处理器类

//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public void doException(Exception ex){
        System.out.println("嘿嘿,异常你哪里跑!")
    }
}

?确保SpringMvcConfig能够扫描到异常处理器类

11.2.2、让程序抛出异常

@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
    //出现数学异常
    int i = 1/0;
    Book book = bookService.getById(id);
    Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
    String msg = book != null ? "" : "数据查询失败,请重试!";
    return new Result(code,book,msg);
}

11.2.3、运行程序,测试

修改异常处理器类返回结果给前端

//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doException(Exception ex){
        System.out.println("嘿嘿,异常你哪里跑!")
        return new Result(666,null,"嘿嘿,异常你哪里跑!");
    }
}

使用Postman测试:

?至此,就算后台执行的过程中抛出异常,最终也能按照我们和前端约定好的格式返回给前端。

知识点1:@RestControllerAdvice

名称:@RestControllerAdvice

类型:类注解

位置:Rest风格开发的控制器增强类定义上方

作用:为Rest风格开发的控制器类做曾强

说明:此注解自带@ResponseBody注解、@ControllerAdvice@Component注解,具备对应的功能

知识点2:@ExceptionHandler

名称:@ExeptionHandler

类型:方法注解

位置:专用于异常处理的控制器方法上方

作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行

说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常

11.3、项目异常处理方案

11.3.1、异常分类

1、业务异常(BusinessException):

1.1、规范的用户行为产生的异常、

用户在页面输入内容的时候为按照指定的格式进行数据的填写(数字写为字符串)

1.2、不规范的用户行为操作产生的异常

用户故意传递错误的数据

2、系统异常(SystemException)

项目运行过程中可预计但无法避免的异常(数据库或服务器宕机)

3、其他异常(Exception)

编程人员未预计到的异常(用到的文件不存在)

将异常分类后,针对不同类型的异常,要提供具体的解决方案

11.3.2、异常解决方案

1、业务异常(BusinessException)

发送对应的消息传递给用户,提醒规范操作,常见的就是提示用户名已存在或者密码格式不正确

2、系统异常(SystemException)

步骤1:发送固定的消息传递给用户,安抚用户(系统繁忙,请稍后再试;系统正在维护升级,请稍后再试;系统出现问题,请联系系统管理员等)

步骤2:发送特定消息给运维成员,提醒维护(可以发送短信、邮箱或者是公司内部通信软件)

步骤3:记录日志(发消息和记录日志对用户来说是不可见的,属于后台程序)

3、其他异常(Exception)

步骤1:发送固定的消息给用户,安抚用户

步骤2:发送特定的消息给编程人员,提醒维护(纳入预期范围内,一般是程序员没有考虑全,比如未做非空校验等)

步骤3:记录日志:

11.3.3、异常解决方案的具体实现

思路:

1、先通过自定义异常,完成BusinessException和SystemException的定义

2、将其他异常包装成自定义异常类型

3、在异常处理器类中对不同的异常进行处理

步骤1:自定义异常处理器

//自定义异常处理器,用于封装异常信息,对异常进行分类
public class SystemException extends RuntimeException{
    private Integer code;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }
    public SystemException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
}

//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{
    private Integer code;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }
    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
}

说明:

让自定义异常类继承RuntimeException的好处是,后期在抛出这两个异常的时候,就不用在try...catch...或throws了

自定义异常类中添加code属性的原因是为了更好的区分异常时来自哪个业务的

步骤2:将其他异常包成自定义异常

具体的包装方式有:

方式一:try{}catch(){}在catch中重新定义throw我们的自定义异常即可

方式二:直接throw自定义异常即可

public Book getById(Integer id) {
    //模拟业务异常,包装成自定义异常
    if(id == 1){
        throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
    }
    //模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
    try{
        int i = 1/0;
    }catch (Exception e){
        throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
    }
    return bookDao.getById(id);
}

上面为了使code更专业,我们在Code类中在新增需要的属性

//状态码
public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;
    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;
    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    public static final Integer BUSINESS_ERR = 60002;
}

?步骤3:处理器中处理自定义异常

//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {

    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

?步骤4:测试

如果传入的参数为1,会报BusinessException

如果传入其他参数,会报SystemException

?

?对于异常我们就已经处理完成了,不管后台哪一层抛出异常,都会以我们与前端约定好的方式进行返回,前端只需要把信息获取到,根据返回的正确与否来展示不同的内容即可。

11.3.4、小结:

以后项目中的异常处理方式为:

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:40:46  更:2022-10-31 11:43:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 11:14:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码