关于Web应用的全局异常处理,上一篇介绍了ControllerAdvice
结合@ExceptionHandler
的方式来实现web应用的全局异常管理;
本篇博文则带来另外一种并不常见的使用方式,通过实现自定义的HandlerExceptionResolver
,来处理异常状态
上篇博文链接: SpringBoot系列教程web篇之全局异常处理
I. 环境搭建
首先得搭建一个web应用才有可能继续后续的测试,借助SpringBoot搭建一个web应用属于比较简单的活;
创建一个maven项目,pom文件如下
1 | <parent> |
II. HandlerExceptionResolver
1. 自定义异常处理
HandlerExceptionResolver
顾名思义,就是处理异常的类,接口就一个方法,出现异常之后的回调,四个参数中还携带了异常堆栈信息
1 |
|
我们自定义异常处理类就比较简单了,实现上面的接口,然后将完整的堆栈返回给调用方
1 | public class SelfExceptionHandler implements HandlerExceptionResolver { |
仔细观察上面的代码实现,有下面几个点需要注意
- 为了确保中文不会乱码,我们设置了返回头
response.addHeader("Content-Type", "text/html; charset=UTF-8");
如果没有这一行,会出现中文乱码的情况 - 我们纯后端应用,不想返回视图,直接想Response的输出流中写入数据返回
response.getWriter().append("自定义异常处理!!! \n").append(msg).flush();
; 如果项目中有自定义的错误页面,可以通过返回ModelAndView
来确定最终返回的错误页面 - 上面一个代码并不会直接生效,需要注册,可以在
WebMvcConfigurer
的子类中实现注册,实例如下
1 |
|
2. 测试case
我们依然使用上篇博文的用例来测试
1 |
|
下面分别是404异常和500异常的实测情况
500异常会进入我们的自定义异常处理类, 而404依然走的是默认的错误页面,所以如果我们需要捕获404异常,依然需要在配置文件中添加
1 | # 出现错误时, 直接抛出异常 |
为什么404需要额外处理?
下面尽量以通俗易懂的方式说明下这个问题
- java web应用,除了返回json类数据之外还可能返回网页,js,css
- 我们通过
@ResponseBody
来表明一个url返回的是json数据(通常情况下是这样的,不考虑自定义实现) - 我们的
@Controller
中通过@RequestMapping
定义的REST服务,返回的是静态资源 - 那么js,css,图片这些文件呢,在我们的web应用中并不会定义一个REST服务
- 所以当接收一个http请求,找不到url关联映射时,默认场景下不认为这是一个
NoHandlerFoundException
,不抛异常,而是到静态资源中去找了(静态资源中也没有,为啥不抛NoHandlerFoundException呢?这个异常表示这个url请求没有对应的处理器,但是我们这里呢,给它分配到了静态资源处理器了ResourceHttpRequestHandler
)
针对上面这点,如果有兴趣深挖的同学,这里给出关键代码位置
1 | // 进入方法: `org.springframework.web.servlet.DispatcherServlet#doDispatch` |
3. 小结
本篇博文虽然也介绍了一种新的全局异常处理方式,实现效果和ControllerAdvice
也差不多,但是并不推荐用这种方法, 原因如下
HandlerExceptionResolver
的方式没有ControllerAdvice
方式简介优雅- 官方提供的
DefaultHandlerExceptionResolver
已经非常强大了,基本上覆盖了http的各种状态码,我们自己再去定制的必要性不大
II. 其他
web系列博文
- 191010-SpringBoot系列教程web篇之全局异常处理
- 190930-SpringBoot系列教程web篇之404、500异常页面配置
- 190929-SpringBoot系列教程web篇之重定向
- 190913-SpringBoot系列教程web篇之返回文本、网页、图片的操作姿势
- 190905-SpringBoot系列教程web篇之中文乱码问题解决
- 190831-SpringBoot系列教程web篇之如何自定义参数解析器
- 190828-SpringBoot系列教程web篇之Post请求参数解析姿势汇总
- 190824-SpringBoot系列教程web篇之Get请求参数解析姿势汇总
- 190822-SpringBoot系列教程web篇之Beetl环境搭建
- 190820-SpringBoot系列教程web篇之Thymeleaf环境搭建
- 190816-SpringBoot系列教程web篇之Freemaker环境搭建
- 190421-SpringBoot高级篇WEB之websocket的使用说明
- 190327-Spring-RestTemplate之urlencode参数解析异常全程分析
- 190317-Spring MVC之基于java config无xml配置的web应用构建
- 190316-Spring MVC之基于xml配置的web应用构建
- 190213-SpringBoot文件上传异常之提示The temporary upload location xxx is not valid
项目源码
- 工程:https://github.com/liuyueyi/spring-boot-demo
- 项目:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/209-web-error
1. 一灰灰Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
- 一灰灰Blog个人博客 https://blog.hhui.top
- 一灰灰Blog-Spring专题博客 http://spring.hhui.top
Be the first person to leave a comment!