一网打尽 @ExceptionHandler、HandlerExceptionResolver、@controlleradvice 三兄弟!
把 @ExceptionHandler、HandlerExceptionResolver、@controlleradvice 三兄弟放在一起来写更有比较性。这三个东西都是用来处理异常的,但是它们使用的场景都不一样。看本文给你详细的讲解,再也不怕面试被问到了!
这三个注解都是来自于 SpringMVC 的,都能进行异常处理。
Java 程序员都非常的痛恨异常,很多人讨厌 Java 就是因为它的异常处理机制。到处的 try-catch-finally,再不是就是到处抛出异常。
所以 Spring 深知 Java 的疼点,推出了:@ExceptionHandler、HandlerExceptionResolver、@controlleradvice 来方便我们处理一些异常!
@ExceptionHandler 注解
用于局部方法捕获,与抛出异常的方法处于同一个 Controller 类。源码如下:
|
1
2
3
4
5
6
|
@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ExceptionHandler { Class<? extends Throwable>[] value() default {};} |
从源码中可以看出,@ExceptionHandler 注解只能作用为对象的方法上,并且在运行时有效,value() 可以指定异常类。由该注解注释的方法可以具有灵活的输入参数。
异常参数可以包括一般的异常或特定的异常(即自定义异常),如果注解没有指定异常类,会默认进行映射。
用法代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Controllerpublic class XttblogController { @ExceptionHandler({NullPointerException.class}) public String exception(NullPointerException e) { System.out.println(e.getMessage()); e.printStackTrace(); return "null pointer exception"; } @RequestMapping("test") public void test() { throw new NullPointerException("出错了!"); }} |
上面这段代码只会捕获 XttblogController 类中的 NullPointerException 异常。
HandlerExceptionResolver 接口
HandlerExceptionResolver 是 Spring 提供的一个接口。它可以用来处理全局异常!
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
@Componentpublic class GlobalExceptionResolver implements HandlerExceptionResolver{ private ObjectMapper objectMapper; public CustomMvcExceptionHandler() { objectMapper = new ObjectMapper(); } @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,Object o, Exception ex) { response.setStatus(200); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding("UTF-8"); response.setHeader("Cache-Control", "no-cache, must-revalidate"); Map<String, Object> map = new HashMap<>(); if (ex instanceof NullPointerException) { map.put("code", ResponseCode.NP_EXCEPTION); } else if (ex instanceof IndexOutOfBoundsException) { map.put("code", ResponseCode.INDEX_OUT_OF_BOUNDS_EXCEPTION); } else { map.put("code", ResponseCode.CATCH_EXCEPTION); } try { map.put("data", ex.getMessage()); response.getWriter().write(objectMapper.writeValueAsString(map)); } catch (Exception e) { e.printStackTrace(); } return new ModelAndView(); }} |
在 Spring 源码中,我们可以看出它会获取一个实现了 HandlerExceptionResolver 接口的列表
List<HandlerExceptionResolver> resolvers; 如果这个列表不为空,则循环处理其中的异常。
HandlerExceptionResolve 虽然能够处理全局异常,但是 Spring 官方不推荐使用它。
@controlleradvice 注解
另外一个能够处理全局异常的就是 @controlleradvice 注解了。
@controlleradvice 注解根据它的源码,我们知道它也只能作用在类上,并且作用于运行时。下面我们来看一个例子。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@ControllerAdvicepublic class ExceptionController { @ExceptionHandler(RuntimeException.class) public ModelAndView handlerRuntimeException(RuntimeException ex) { if (ex instanceof MaxUploadSizeExceededException) { return new ModelAndView("error").addObject("msg", "文件太大!"); } return new ModelAndView("error").addObject("msg", "未知错误:" + ex); } @ExceptionHandler(Exception.class) public ModelAndView handlerMaxUploadSizeExceededException(Exception ex) { if (ex != null) { return new ModelAndView("error").addObject("msg", ex); } return new ModelAndView("error").addObject("msg", "未知错误:" + ex); }} |
需要注意的是,@ControllerAdvice 一般是和 @ExceptionHandler 组合在一起使用的。官方也推荐用这种方式处理统一全局异常。
一网打尽 @ExceptionHandler、HandlerExceptionResolver、@controlleradvice 三兄弟!的更多相关文章
- Nancy之Pipelines三兄弟(Before After OnError)
一.简单描述 Before:如果返回null,拦截器将主动权转给路由:如果返回Response对象,则路由不起作用. After : 没有返回值,可以在这里修改或替换当前的Response. OnEr ...
- 好用的排名函数~ROW_NUMBER(),RANK(),DENSE_RANK() 三兄弟
排名函数三兄弟,一看名字就知道,都是为了排名而生!但是各自有各自的特色!以下一个例子说明问题!(以下栗子没有使用Partition By 的关键字,整个结果集进行排序) RANK 每个值一个排名,同样 ...
- sql语句中----删除表数据的"三兄弟"
说到删除表数据的关键字,大家记得最多的可能就是delete了 然而我们做数据库开发,读取数据库数据.对另外的两兄弟用得就比较少了 现在来介绍另外两个兄弟,都是删除表数据的,其实也是很容易理解的 老大- ...
- @ExceptionHandler和@ControllerAdvice统一处理异常
//@ExceptionHandler和@ControllerAdvice统一处理异常//统一处理异常的controller需要放在和普通controller同级的包下,或者在ComponentSca ...
- Promise的三兄弟:all(), race()以及allSettled()
摘要: 玩转Promise. 原文:Promise 中的三兄弟 .all(), .race(), .allSettled() 译者:前端小智 Fundebug经授权转载,版权归原作者所有. 从ES6 ...
- 设计模式系列之工厂模式三兄弟(Factory Pattern)
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- Mysql 中写操作时保驾护航的三兄弟!
这期的文章主要是讲述写操作过程中涉及到的三个日志文件,看过前几期的话可能你或多或少已经有些了解了(或者从别的地方也了解过).比如整个写操作过程中用到的两阶段提交,又或者是操作过程中涉及到的日志文件,但 ...
- 站长管理服务器必读:Ftp、Ftps与Sftp三兄弟的不同与区别以及部署全指引
文章标题: 站长管理服务器必读:Ftp.Ftps与Sftp三兄弟的不同与区别以及部署全指引 关键字 : ftp,sftp,freesshd,ftps 文章分类: 教程 创建时间: 2020年3月23日 ...
- SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-005- 异常处理@ResponseStatus、@ExceptionHandler、@ControllerAdvice
No matter what happens, good or bad, the outcome of a servlet request is a servlet response. If an e ...
随机推荐
- thinkphp url和路由
一.入口模块修改 修改public下的index 加入 define('BIND_MODULE','admin'); 即可将入门模块绑定到admin模块 <?php // [ 应用入口文件 ] ...
- Linux下git安装配置
一.Linux下git安装配置 2013-07-28 20:32:10| 分类: 默认分类 | 标签:linux git server |举报|字号 订阅 http://abomby ...
- 对微信小程序的研究2
.json 后缀的 JSON 配置文件 .wxml 后缀的 WXML 模板文件 .wxss 后缀的 WXSS 样式文件 .js 后缀的 JS 脚本逻辑文件 JSON 配置 我们可以看到在项目的根目录有 ...
- 正则化的L1范数和L2范数
范数介绍:https://www.zhihu.com/question/20473040?utm_campaign=rss&utm_medium=rss&utm_source=rss& ...
- Counter的数据统计功能
Counter是dict的子类,一般用于统计,默认排序是从大到小 from collections import Counter # 输入iterable对象即可 str_counter = Coun ...
- CoreData新增字段
1. 在模型文件的Entity里面增加字段名 2. Xcode工具栏选择Edtor->Creat NSManagerObject SubClass->...->生成新的关联文件 3. ...
- 2018年第九届山东省ACM省赛总结
去年打完区域赛之后,面对着两个队友都去找实习的情况,我自己对今年省赛还是有点慌的.不只一次的像我的队友说明自己很慌,但是老曹跟会长都说:“没事,慌啥!”前几场训练赛因为老曹跟秋洁有面试有时候只能一个人 ...
- 28 August
单调队列复习. 投资 (invest) 给定一带符号整数数列,求长度为 \([s, e]\) 的子区间的和的最大值.(最大子段和) 降二维为一维,for循环枚举区间右端点.预处理前缀和,问题转化为找到 ...
- python脚本-上传apk至蒲公英
import requests import os #账号配置信息 url = "https://upload.pgyer.com/apiv1/app/upload" uKey = ...
- canvas绘制验证码
css样式: <style> body{ text-align: center; } canvas{ background:#ddd; } </style> body中添加标签 ...