测试开发专题:spring-boot统一异常捕获
java异常介绍
异常时相对于return的一种退出机制,可以由系统触发,也可由程序通过throw语句触发,异常可以通过try/catch语句进行捕获并处理,如果没有捕获,则会导致程序退出并输出异常栈信息,异常有不同的类型,所有异常类都有一个共同的父类Throwable,下面我们先从Throwable开始介绍。
Throwable
Throwable
是所有异常类的父类,有四个构造方法
public Throwable(Throwable cause)
public Throwable(String message, Throwable cause)
public Throwable(String message)
public Throwable()
主要有两个类,一个是message,表示异常的消息,一个是cause,表示触发该异常的其他异常,异常可以形成一个异常链,上层的异常由底层到的异常触发,cause表示底层异常。
异常体系
java定义了非常多的异常类,来表示各种类型的异常,下面的图示是部分的异常类:
Throwable是所有异常类的基类,它有两个子类:Error和Exception。
- Error错误
操作系统或者虚拟机发生的错误,这个时候程序是跑不起来的,代码是无法处理的,一般表示系统错误或者资源耗尽,由java系统自己处理,比如图示中给出的:虚拟机错误、栈溢出、内存溢出等错误
- Exception
表示应用程序错误,是可以通过代码处理的,有两大类:一类是受检异常(checked exception),一类是非受检异常(uncheck exception),也就是runtime异常,他两的区别就在于java是如何对待他们的,受检异常,java会要求强制进行处理,不然编译时不通过的,对于非受检异常则没有这个强制性的要求。
解释
该怎么理解受检异常和非受检异常呢,我的理解就是做某件事的时候我们能够顺利的按照我们预期的做完,但是实际上呢可能会出现各种各样的情况,这种可能出现的情况就把他称之为异常,这种异常有的我们能处理,有的我们不能处理,能处理的就把它称作为受检异常,不能处理的称作为非受检异常。
比如说,客户端发送一个请求,要查询数据库,那有可能找到有可能没找到,没找到的话,就应该抛出runtime异常,再比如要去读取文件,文件可能是不存在的,那就应该抛出checked exception,这其实就是bug,我们应该去处理的。
怎么理解呢,比如读取文件,当文件不存在,发生异常,能处理么,当然可以处理啊,怎么处理,把文件路径改成正确的不就行了。从某种意义上来说,checked异常是真正的bug
没有办法处理的情况,比如说用户输入ID为2,查询记录能找到,但是如果输入2000就找不到了,这里的找不到就是一种异常情况,就需要产生一个运行时异常也就是非受检异常。
已知异常和未知异常
上面我们提到的受检异常 unchecked exception
和运行时异常 RuntimeException
都是从java语法层面来说的,那从程序开发者的角度来说,分为两类:已知异常和未知异常。
已知异常和未知异常,其实就在于我们程序员是否主动的去处理异常。
- 未知异常:当代码中未对一些情况做出处理而引发的异常,这就是未知异常,一般这种异常都是因为服务端的代码写的有问题的,对于前段开发或者用户,都是无意义的,记录日志供自己查看就行了。
- 已知异常:更多的时候表示的是一种消息,用来提示用户的输入是否有问题,只不过这里我们用异常的形式来处理,当然也可以通过其他方式处理,比如当做结果去返回,也是可以的,但是这种方式不如全部都看做异常,通过全局的异常处理器直接处理来的简单。
Spring-Boot全局异常处理器
在使用spring-boot进行开发到的时候,有时我们需要对程序中抛出的异常进行统一的处理,spring-boot预留了响应的扩展点,我们只需要按照要求的方式去自定义自己的实现即可。
@ControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler(value = Exception.class)
public void handleHttpException(HttpServletRequest req, Exception ex){
}
}
@ControllerAdvice
表明GlobalExceptionAdvice是一个异常的处理类,具体的处理方法通过 @ExceptionHandler
进行标记,通过value来指定能够处理的异常类型。异常的处理方法需要传入两个参数,一个是HttpServletRequest请求对象,可以从这里获取请求相关的一些信息,比如请求的url或者参数等,另一个是Exception就是抛出的异常。
模拟异常发生
我们在异常的处理方法中打印一条语句
@ControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler(value = Exception.class)
public void handleHttpException(HttpServletRequest req, Exception ex){
System.out.println("发生异常了");
}
}
然后再Controller里抛出一个异常
@RestController
public class BannerController {
@RequestMapping(value = "/v2/banner", method = {RequestMethod.GET})
public String test() throws Exception {
throw new Exception("我抛出来的");
}
}
启动程序后在浏览器中访问路由,可以看到在控制台中打印出了预期的信息
当然在实际开发中,我们可能要多异常进行区分,该抛出什么类型的异常,异常处理函数可也不只一个,还要对返回的异常信息进行自定义。
自定义异常类
当我们需要自定义异常类的时候,是该继承自exception呢,还是继承RuntimeException?下面我们就来讨论一下。
当用户访问一个不存在的资源的时候,很明显这种情况我们是处理不了的,而且这种情况我们是可以判断出来的,所以这里应该使用Runtime异常。
HttpException
是所有自定义运行时异常类的基类,这里定义两个状态码,一个code是我们业务层面的定义,一个httpStatusCode是http请求的,资源不存在的异常定义为 NotFoundException
在controller里面抛出这个异常,
那之前定义的 GlobalExceptionAdvice
能够监听到这个异常呢?
当然能,NotFoundException
是 HttpException
的子类,HttpException
是 RuntimeException
的子类,RuntimeException
又是 Exception
的子类,@ExceptionHandler(value = Exception.class)
全局异常处理器里指定的能够处理的异常类是 Exception
自然也能处理 NotFoundException
。
但是这里也有不同的地方,我们自定义的 HttpException
是多了两个扩展字段的,code
和 httpStatusCode
,所以在全局异常处理器里需要对异常的类型进行判断,如果是自定义的就需要添加这两个字段。
这里呢有两种方式进行处理:一种是在之前的异常处理方法里面,进行类型判断,另一种呢是可以再添加一个异常处理方法,专门处理自定义异常类
这里我们可以考虑一下,当我们抛出 NotFoundException
异常的时候,是会进入哪一个异常处理方法里?还是说两个都进呢?
我们可以来试验一下,启动程序后,看看在控制台打印的是什么
在浏览器里访问路由以后,控制台显示了handleHttpException异常处理方法里到的打印语句输出的内容。
可以看到多个异常处理方法时可以同时存在的,各自处理自己所能处理的异常类。
下篇文章,我们来探讨一下,如何自定义异常的返回信息,敬请关注,博客原文
欢迎大家去 我的博客 瞅瞅,里面有更多关于测试实战的内容哦!!
测试开发专题:spring-boot统一异常捕获的更多相关文章
- Spring Boot 统一异常这样处理和剖析,安否?
话说异常 「欲渡黄河冰塞川,将登太行雪满天」,无论生活还是计算机世界难免发生异常,上一篇文章RESTful API 返回统一JSON数据格式 说明了统一返回的处理,这是请求一切正常的情形:这篇文章将说 ...
- Spring Boot 全局异常捕获
import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.Control ...
- spring boot统一异常页面
只需要创建一个类就可以了 package com.ulic.gis.securityManage.controller; import java.util.Map; import javax.serv ...
- 测试开发专题:spring-boot自定义异常返回
上文测试开发专题:spring-boot统一异常捕获我们讨论了java异常以及如何使用Spring-Boot捕获异常,但是没有去说捕获异常后该如何进一步处理,这篇文章我们将对这个遗留的问题进行讨论. ...
- Spring Boot 全局异常配置
Spring Boot 全局异常配置,处理异常控制器需要和发生异常的方法在一个类中.使用 ControllerAdvice 注解 package com.li.controller; import o ...
- spring boot 统一接口异常返回值
创建业务 Exception 一般在实际项目中,推荐创建自己的 Exception 类型,这样在后期会更容易处理,也比较方便统一,否则,可能每个人都抛出自己喜欢的异常类型,而造成代码混乱 Servic ...
- spring boot 拦截异常 统一处理
spring boot 默认情况下会映射到 /error 进行异常处理,提示不友好,需要自定义异常处理,提供友好展示 1.自定义异常类(spring 对于 RuntimeException 异常才会进 ...
- 后端开发实践——Spring Boot项目模板
在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...
- Spring Boot统一异常处理实践
摘要: SpringBoot异常处理. 原文:Spring MVC/Boot 统一异常处理最佳实践 作者:赵俊 前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 对于很多 ...
- 快速开发架构Spring Boot 从入门到精通 附源码
导读 篇幅较长,干货十足,阅读需花费点时间.珍惜原创,转载请注明出处,谢谢! Spring Boot基础 Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计 ...
随机推荐
- G++编译链接的那些事
语言 CPP 前言 虽然 VSCodeC++ 编辑器非常受大家的欢迎,无论是大佬还是小白都说对其爱不释手... 我...用了一段时间后发现实在是麻烦,配置往往花费我大量时间.可以说真的是吃力不 ...
- W - Palindrome HDU - 1513
题目大意: 插入最少的字符,使原字符串成为回文串. 题解: LCS问题,将字符串反转,然后求这俩字符串的LCS,总长度减去LCS即可(多组输入). N最大是5E3,直接用二维数组会超内存.所以要用到滚 ...
- python selenium模块 xpath定位
''' 附w3xpath语法地址 https://www.w3school.com.cn/xpath/xpath_syntax.asp 总结: 返回匹配到所有符合条件的第一个节点,对象是 <cl ...
- 靠!安装了macOS Catalina(10.15.4)后,文件系统都乱套了
最近闲来无事,决定将我的两台apple电脑升级成最新的苹果系统(macOS Catalina),当然,由于以前升级过多次mac系统,所以毫不犹豫从app store下载了最新的macOS Cetali ...
- 负载均衡服务之HAProxy基础配置(三)
前文我们聊到了haproxy的代理配置段中比较常用的配置指令的用法以及说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12770930.html:今天我们来 ...
- vue3开发饿了么商城2020年新版本
带手机验证码登陆, 带全套购物车系统 带数据库 前后端分离开发 带定位用户功能 数据库代码为本地制作好了 带支付宝支付系统 带django开发服务器接口教程 地址: https://www.dua ...
- 关于“xxx”object is not callable的异常
参考博文:https://blog.csdn.net/yitiaodashu/article/details/79016671 所谓callable对象是指一个后边可以加()的对象,比如函数, 所以这 ...
- 大数据并行计算框架Spark
Spark2.1. http://dblab.xmu.edu.cn/blog/1689-2/ 0+入门:Spark的安装和使用(Python版) Spark2.1.0+入门:第一个Spark应用程序: ...
- Android-网页解析-gson的使用
相对于较为传统的Json解析来说,google共享的开源Gson在解析速度和所使用的内存在有着明显的优势,虽然说阿里巴巴也提供了fastgson包,但是它跟Gson的处理速度大同小异,只是底层实现的原 ...
- php算--------法
<?php //冒泡排序:两两交换数值,最小的值在最左边,就如最轻的气泡在最上边.对整列数两两交换一次//最小的数在最左边,每次都能得一个在剩下的数中的最小 的数//“冒”出来的数组成一个有序区 ...