一网打尽 @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 ...
随机推荐
- Wannafly挑战赛27 C蓝魔法师
链接Wannafly挑战赛27 C蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),\(n,k\leq 2*10^3\) 假设我们正在考虑\(i\)这个子树,那么 ...
- 手工实现Array List和Linked List
Array List样例: /** * 增加泛型 * 自动增加数组容量 * 增加set.get方法:增加数组边界的检查 * 增加remove方法 */package cn.study.lu.four; ...
- php-redis 使用命令
PHP 使用redis 一些命令参考:https://www.jianshu.com/p/68b7114a1d70
- 英语单词composing
composing 来源——书籍Python.Crash.Course.2015.11 Using Individual Values from a List You can use individu ...
- dubbo-go 中的 TPS Limit 设计与实现
前言 Apache Dubbo 是由阿里开源的一个RPC框架,除了基本的 RPC 功能以外,还提供了一整套的服务治理相关功能.目前它已经是 Apache 基金会下的顶级项目. 而 dubbo-go 则 ...
- 阿里云推出SRT+杜比全景声直播方案,低成本打造高质量直播观感体验
超过200个国家和地区共5144万人观看:浙江卫视.东方卫视55城总收视达2.39,稳居同时段市场第一:优酷直播间63%观看晚会的用户参与了互动:微博68.2亿的主话题阅读量:2019天猫双11狂欢夜 ...
- OC + RAC (九) 过滤
// 跳跃 : 如下,skip传入2 跳过前面两个值 // 实际用处: 在实际开发中比如 后台返回的数据前面几个没用,我们想跳跃过去,便可以用skip - (void)skip { RACSubjec ...
- python-zx笔记10-断言
断言 断言内容是自动化脚本的重要内容,正确设置断言以后才能帮助我们判断测试用例执行结果. 断言方法 assertEqual(a, b) 判断a==b assertNotEqual(a, b) 判断a! ...
- 仅对原表新增列的全量数据.csv
w
- linux使用pigz多线程压缩
因为tar zip是单线程的压缩,压缩起来很慢,这个使用使用pigz工具辅助就会使用多线程了. 安装 sudo apt install pigz 压缩 tar cvf - test.txt | pig ...