Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

本文创建基于 @RestControllerAdvice 全局异常类示例。其实,无论是 @ControllerAdvice 还是 @RestControllerAdvice 都是可以捕捉 @Controller 和 @RestController 抛出的异常。

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

一、@ControllerAdvice vs @RestControllerAdvice

@RestControllerAdvice是@ControllerAdvice和@ResponseBody的组合。

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

可以简单地理解其差异性,如下所示:

  • @RestControler = @Controller + @ResponseBody
  • @RestControllerAdvice = @ControllerAdvice + @ResponseBody

@RestControllerAdvice 注解处理RESTful API异常会更加方便一点。

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类专栏Spring Cloud Alibaba微服务实战作者:软件架构29.8币126人已购查看

二、创建自定义的全局异常处理类 MyRestExceptionController

@RestControllerAdvice 注解是 Spring Boot 用于捕获 @Controller 和 @RestController 层系统抛出的异常。注意,如果已经编写了 try-catch 且在 catch 模块中没有使用 throw 抛出异常, 则 @RestControllerAdvice 捕获不到异常。

@ExceptionHandler 注解用于指定方法处理的 Exception 的类型。

在示例项目中添加MyRestExceptionController控制器,如图所示:

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

MyRestExceptionController控制器代码如下所示:

/**

* 基于@ControllerAdvice注解的全局异常统一处理只能针对于Controller层的异常

* 为了和Controller 区分 ,我们可以指定 annotations = RestController.class,

* 那么在Controller中抛出的异常,这里就不会被捕捉。

* */

@RestControllerAdvice(annotations = RestController.class)

public class MyRestExceptionController {

private static final Logger logger= LoggerFactory.getLogger(MyRestExceptionController.class);

@Autowired

private ErrorAttributes errorAttributes;

/**

* 处理所有的Controller层面的异常

* */

@ExceptionHandler(Exception.class)

@ResponseBody

public final ResponseMessage handleAllExceptions(Exception ex, ServletWebRequest request){

logger.error(“Exception Handler”, ex);

Map<String, Object> attr = errorAttributes.getErrorAttributes(request, true);

return ResponseMessage.fail(ex.getMessage(), attr);

}

}

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类专栏SkyWalking分布式链路追踪和监控作者:软件架构19.9币109人已购查看

三、创建用于测试的 RestController

在示例项目中创建IndexRestController控制器,如图所示,用来进行演示。

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

IndexRestController 编写了4个 api 方法:

  • /index 是正常的方法;
  • /err 是人为抛出异常;
  • /matherr 除数为0的异常 ;
  • /catch 用了 try-catch 但没有抛出异常,不会被捕捉。

四个 api 其中 /err、/matherr 将会被 MyRestExceptionController 捕捉。

IndexRestController代码如下所示:

@RestController

@RequestMapping(“api”)

public class IndexRestController {

@GetMapping(“/index”)

public ResponseMessage index(){

Map<String,Object> map=new HashMap<>();

map.put(“status”,”0″);

map.put(“message”,”Spring Cloud Alibaba微服务实战技术专栏”);

return ResponseMessage.success(map);

}

}

正常返回结果,如图所示:

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

/**

* 这里人为手动抛出一个异常

* */

@RequestMapping(“/err”)

public Map err(){

throw new RuntimeException(“抛出一个异常”);

}

访问localhost:8080/api/err,返回如下结果:

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

/**

* 这里抛出的是 RuntimeException 不可查异常,虽然没有使用 try-catch 来捕捉 但系统以及帮助我们抛出了一次

* */

@RequestMapping(“/matherr”)

public Map matherr(){

Map<String,Object> map=new HashMap<>();

map.put(“status”,”0″);

map.put(“message”,”正常的输出”);

int j=0;

Integer i=9/j;

return map;

}

访问
localhost:8080/api/matherr,返回结果如下:

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

/**

* 使用了 try-catch 来捕捉异常,但没有抛出异常

* */

@RequestMapping(“/catch”)

public ResponseMessage nocatch(){

Map<String,Object> map=new HashMap<>();

map.put(“status”,”0″);

map.put(“message”,”正常的输出 注意这里使用了 try-catch 来捕捉异常,但没有抛出异常,所以没有异常,因为这里抛出的是 RuntimeException 不可查异常,系统也不会报错。”);

int j=0;

try{

Integer i=9/j;

}catch (Exception ex){

}

return ResponseMessage.success(map);

}

注意:这里使用了 try-catch 来捕捉异常,所以可以正常获取到返回结果。

访问localhost:8080/api/catch,返回结果如下所示:

Spring Boot全局异常处理入门-基于@RestControllerAdvice异常类

需要清楚的是,@ControllerAdvice 和 @RestControllerAdvice 是应用于对Spring MVC中的控制器抛出的异常进行处理,而对于404这样不会进入控制器处理的异常不起作用,所以此时还是要依靠ErrorController来处理。

内容出处:,

声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.net/procedure/25642.html

发表评论

登录后才能评论