在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
*/
@InitBinder
public void initWebBinder(WebDataBinder binder){
//对日期的统一处理
binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
//添加对数据的校验
//binder.setValidator();
} /**
* 把值绑定到Model中,使全局@RequestMapping可以获取到该值
* @param model
*/
@ModelAttribute
public 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
*/
@InitBinder
public void initWebBinder(WebDataBinder binder){ } /**
* 把值绑定到Model中,使全局@RequestMapping可以获取到该值
* @param model
*/
@ModelAttribute
public 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。

精通Spring Boot---使用@ControllerAdvice处理异常的更多相关文章

  1. Spring Boot 系列 @ControllerAdvice 拦截异常并统一处理

    ControllerAdvice用法解析 简介 通过@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置. 注解了@Controller的类的方法可以使用@Exception ...

  2. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  3. 精通Spring Boot

    原 精通Spring Boot—— 第二十一篇:Spring Social OAuth 登录简介 1.什么是OAuth OAuth官网介绍是这样的: An open protocol to allow ...

  4. Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析

    前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...

  5. spring boot如何处理异步请求异常

    springboot自定义错误页面 原创 2017年05月19日 13:26:46 标签: spring-boot   方法一:Spring Boot 将所有的错误默认映射到/error, 实现Err ...

  6. spring boot中@ControllerAdvice的用法

    @ControllerAdvice ,这是一个增强的 Controller.使用这个 Controller ,可以实现三个方面的功能: 全局异常处理 全局数据绑定 全局数据预处理 灵活使用这三个功能, ...

  7. 二、spring boot 1.5.4 异常控制

    spring boot 已经做了统一的异常处理,下面看看如何自定义处理异常 1.错误码页面映射 1.1静态页面 必须配置在 resources/static/error文件夹下,以错误码命名 下面是4 ...

  8. Spring Boot Maven Plugin打包异常及三种解决方法:Unable to find main class

    [背景]spring-boot项目,打包成可执行jar,项目内有两个带有main方法的类并且都使用了@SpringBootApplication注解(或者另一种情形:你有两个main方法并且所在类都没 ...

  9. Spring boot 文件路径读取异常

    在开发代码中,有一段需要获取resources目录下的一个配置文件(这里写作test.xml). 这段代码在ide中没有任何问题,但是一打成jar包发布到线上,这段代码就会报找不到对应文件的错误. 按 ...

随机推荐

  1. nginx 添加https支持

    自行颁发不受浏览器信任的SSL证书为晒晒IQ网颁发证书.ssh登陆到服务器上,终端输入以下命令,使用openssl生成RSA密钥及证书. # 生成一个RSA密钥 $ openssl genrsa -d ...

  2. 新手写AIDL构建失败:...aidl.exe'' finished with non-zero exit value 1

    最近学习aidl,写demo后编译报错,跟着<Android开发艺术探索>以及网上的一些aidl详解博客敲完后一直编译不过,错误日志如下: Process 'command 'C:\Use ...

  3. [转]logX<X对所有的X>0成立

    本文引用地址:http://blog.sciencenet.cn/blog-1865911-831450.html 此文来自科学网何召卫博客,转载请注明出处. 这个命题网上有多种证法,有人甚至采用斜率 ...

  4. C#数据库(MySQL)帮助类

    using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Configura ...

  5. Arduino连接pH计

    关于arduino连接ph,核心的东西就是对ph传感器返回的信号值进行一系列的操作,注意因为返回的信号很弱,而且外部环境对其影响也很大,所以需要在电路设计上加入一些功能,比如信号放大.滤波等,电路设计 ...

  6. ElasticSearch:华为云搜索CSS 之POC操作记录

    2019/03/06 09:00 ES文档官方:https://support.huaweicloud.com/usermanual-es/es_01_0024.html 华为云区域:华北北京1 ES ...

  7. yum 和 rpm安装mysql彻底删除

    1.yum方式安装的MySQL $ yum remove mysql mysql-server mysql-libs compat-mysql51 $ rm -rf /var/lib/mysq $ r ...

  8. >>我要到处浪系列 之 JS随便投票小脚本

    首先郑重声明:我不是对任何网站或者任何个人或组织有意见,仅仅是觉得 4点几 的评分对某些玩票的片段都太高了,为了落实想法,切实履行公民的投票权,并且 bibibabibobi biubiubiu..所 ...

  9. logback的configuration

    logback的<configuration>只有三个属性: 1.scan[boolean]:当scan被设置为true时,当配置文件发生改变,将会被重新加载.默认值为true. 2.sc ...

  10. C#中?和??用法

       在C#中“?”有三种用法.       1.可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空,例如:string str=null;是正确的.int i= ...