精通Spring Boot —— 第十五篇:使用@ControllerAdvice处理异常
在Spring 3.2中,新增了@ControllerAdvice、@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping、@PostMapping, @GetMapping注解中。
接下来我将通过代码展示如何使用这些注解,以及处理异常。
1.注解的介绍
先定义一个ControllerAdvice。代码如下
/*** @author Lensen* @desc* @since 2018/10/5 11:01*/
@ControllerAdvice
public class MyExceptionHandler {/*** 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器* @param binder*/@InitBinderpublic void initWebBinder(WebDataBinder binder){//对日期的统一处理binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));//添加对数据的校验//binder.setValidator();}/*** 把值绑定到Model中,使全局@RequestMapping可以获取到该值* @param model*/@ModelAttributepublic void addAttribute(Model model) {model.addAttribute("attribute", "The Attribute");}/*** 捕获CustomException* @param e* @return json格式类型*/@ResponseBody@ExceptionHandler({CustomException.class}) //指定拦截异常的类型@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //自定义浏览器返回状态码public Map<String, Object> customExceptionHandler(CustomException e) {Map<String, Object> map = new HashMap<>();map.put("code", e.getCode());map.put("msg", e.getMsg());return map;}/*** 捕获CustomException* @param e* @return 视图*/
// @ExceptionHandler({CustomException.class})
// public ModelAndView customModelAndViewExceptionHandler(CustomException e) {
// Map<String, Object> map = new HashMap<>();
// map.put("code", e.getCode());
// map.put("msg", e.getMsg());
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.setViewName("error");
// modelAndView.addObject(map);
// return modelAndView;
// }
}
需要注意的是使用@ExceptionHandler注解传入的参数可以一个数组,且使用该注解时,传入的参数不能相同,也就是不能使用两个@ExceptionHandler去处理同一个异常。如果传入参数相同,则初始化ExceptionHandler时会失败。
对于@ControllerAdvice注解,我们来看看源码的定义:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] assignableTypes() default {};Class<? extends Annotation>[] annotations() default {};
}
我们可以传递basePackage,声明的类(是一个数组)指定的Annotation参数,具体参考:spring framework doc
2.异常的处理
编写自定义异常类
package com.developlee.errorhandle.exception;/*** @author Lensen* @desc 自定义异常类* @since 2018/10/5 11:04*/
public class CustomException extends RuntimeException {private long code;private String msg;public CustomException(Long code, String msg){this.code = code;this.msg = msg;}public long getCode() {return code;}public void setCode(long code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}
Spring 对于 RuntimeException类的异常才会进行事务回滚,所以我们一般自定义异常都继承该异常类。
编写全局异常处理类
/*** @author Lensen* @desc* @since 2018/10/5 11:01*/
@ControllerAdvice("com.developlee.errorhandle")
public class MyExceptionHandler {/*** 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器* @param binder*/@InitBinderpublic void initWebBinder(WebDataBinder binder){}/*** 把值绑定到Model中,使全局@RequestMapping可以获取到该值* @param model*/@ModelAttributepublic void addAttribute(Model model) {model.addAttribute("attribute", "The Attribute");}/*** 捕获CustomException* @param e* @return json格式类型*/@ResponseBody@ExceptionHandler({CustomException.class}) //指定拦截异常的类型@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //自定义浏览器返回状态码public Map<String, Object> customExceptionHandler(CustomException e) {Map<String, Object> map = new HashMap<>();map.put("code", e.getCode());map.put("msg", e.getMsg());return map;}/*** 捕获CustomException* @param e* @return 视图*/
// @ExceptionHandler({CustomException.class})
// public ModelAndView customModelAndViewExceptionHandler(CustomException e) {
// Map<String, Object> map = new HashMap<>();
// map.put("code", e.getCode());
// map.put("msg", e.getMsg());
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.setViewName("error");
// modelAndView.addObject(map);
// return modelAndView;
// }
}
测试
在controller中抛出自定义异常
/*** @author Lensen* @desc* @since 2018/10/5 11:00*/
@Controller
public class DemoController {/*** 关于@ModelAttribute,* 可以使用ModelMap以及@ModelAttribute()来获取参数值。*/ @GetMapping("/one")public String testError(ModelMap modelMap ) {throw new CustomException(500L, "系统发生500异常!" + modelMap.get("attribute"));}@GetMapping("/two")public String testTwo(@ModelAttribute("attribute") String attribute) {throw new CustomException(500L, "系统发生500异常!" + attribute);}
}
启动应用,范围localhost:8080/one.返回报文为:
{"msg":"系统发生500异常!The Attribute","code":500}
可见我们的@InitBinder和@ModelAttribute注解生效。且自定义异常被成功拦截。如果全部异常处理都返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。@RestControllerAdvice在注解上已经添加了@ResponseBody。
最后,以上示例代码可在我的github.com中找到。
我的个人公众号:developlee的潇洒人生。
关注了也不一定更新,更新就不得了了。
精通Spring Boot —— 第十五篇:使用@ControllerAdvice处理异常相关推荐
- spring boot(一):入门篇
构建微服务:Spring boot 入门篇 什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...
- 坚持的力量 第十五篇
第十五篇 漩涡鸣人 从他身上,我看到了进步和向上的力量,经别人推荐,我发现我渐渐的喜欢上了<火影忍者>. 首先,<火影>中的歌曲很有震撼力和穿透力,产生心灵的共鸣 ...
- spring boot实战(第六篇)加载application资源文件源码分析
前言 在上一篇中了解了spring配置资源的加载过程,本篇在此基础上学习spring boot如何默认加载application.xml等文件信息的. ConfigFileApplicationLis ...
- 秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题
秒杀多线程第十五篇 关键段,事件,互斥量,信号量的"遗弃"问题 在<秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量>中对经典多线程同步互斥问题进行了回 ...
- CCIE理论-第十五篇-IPV6-重分布+ACL+前缀列表
CCIE理论-第十五篇-IPV6-重分布+ACL+前缀列表 重分布前面讲过,这里再讲一次+实操+效果看看 在ipv6中重分布直连路由是需要加上include-connected的 环境 就这么简单哈, ...
- CCIE-LAB-第十五篇-IPV6-BGP+VPN6+RT
CCIE-LAB-第十五篇-IPV6-BGP+VPN6+RT 实际中,思科只会给你5个小时去做下面的全部配置 这个是CCIE-LAB的拓扑图 问题 翻译: 根据这些要求,将IPV6连接从总部通过SP扩 ...
- CCNP-第十五篇-VXLAN(一)
CCNP-第十五篇-VXLAN(一) 到了这个阶段呢,怎么说呢,简单的NP级别的交换我都跳过去了,但是后期会补, 所以这个衔接可能新手或者不会的看的有的迷茫 但是出自个人原因只好这么干了,VXLAN3 ...
- CCNA-第十五篇-DHCP配置+SDN介绍(最后一章)
CCNA-第十五篇-DHCP配置+SDN介绍 各位好,如果有一直看下来的谢谢支持 这里是CCNA的最后一篇了,如果真的能吸收很多内容,那么普通的东西基本上都没什么大问题了.除非就是工作经验 下一篇就到 ...
- Spring Boot:(五)静态资源和拦截器处理
Spring Boot:(五)静态资源和拦截器处理 前言 本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类WebMvcConfigurerAdapter. 正文 前面章节我们也有 ...
最新文章
- python资料书-史上最全Python从入门到资深书籍资料分享!
- 036_jQuery Ajax全局回调函数
- bootstrap后台模板_免费bootstrap后台管理系统模板源码 网站后台模板_后台管理界面...
- [BZOJ4817]树点涂色
- 解决django前端使用iframe标签报错127.0.0.1 refused to connect.
- hdu 1588 Gauss Fibonacci
- RPM + yum 完美完装tomcat
- 必备知识:工业相机相关知识(初学者必备)
- 使用Sugar制作数据可视化大屏的操作过程
- 重装系统后电脑耳机插前面没有声音输出怎么办?
- 20亿美金独角兽Notion,和它在中国的“抄袭”者们
- Code review是个数学问题:从二向箔说起
- zip4j对处理压缩包及压缩包加密处理
- python翻译器怎么用_给宝宝用Python写个支持翻译PDF文档的小软件
- 秒变黑科技的高效电脑软件,请低调收藏!
- JavaWeb项目打包成桌面程序,内嵌浏览器、tomcat、jre、mysql,实现一键安装
- Matlab2017b C++编译器配置
- 关于提取图片中文字区域的算法和实现方法
- Centos 7 安装python 3.8
- 合宙Air101 的LCD怎么用Arudino IDE驱动