本文创建基于 @RestControllerAdvice 全局异常类示例。其实,无论是 @ControllerAdvice 还是 @RestControllerAdvice 都是可以捕捉 @Controller 和 @RestController 抛出的异常。
一、@ControllerAdvice vs @RestControllerAdvice
@RestControllerAdvice是@ControllerAdvice和@ResponseBody的组合。
可以简单地理解其差异性,如下所示:
- @RestControler = @Controller + @ResponseBody
- @RestControllerAdvice = @ControllerAdvice + @ResponseBody
@RestControllerAdvice 注解处理RESTful API异常会更加方便一点。
专栏Spring Cloud Alibaba微服务实战作者:软件架构29.8币126人已购查看
二、创建自定义的全局异常处理类 MyRestExceptionController
@RestControllerAdvice 注解是 Spring Boot 用于捕获 @Controller 和 @RestController 层系统抛出的异常。注意,如果已经编写了 try-catch 且在 catch 模块中没有使用 throw 抛出异常, 则 @RestControllerAdvice 捕获不到异常。
@ExceptionHandler 注解用于指定方法处理的 Exception 的类型。
在示例项目中添加MyRestExceptionController控制器,如图所示:
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);
}
}
专栏SkyWalking分布式链路追踪和监控作者:软件架构19.9币109人已购查看
三、创建用于测试的 RestController
在示例项目中创建IndexRestController控制器,如图所示,用来进行演示。
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);
}
}
正常返回结果,如图所示:
/**
* 这里人为手动抛出一个异常
* */
@RequestMapping(“/err”)
public Map err(){
throw new RuntimeException(“抛出一个异常”);
}
访问localhost:8080/api/err,返回如下结果:
/**
* 这里抛出的是 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,返回结果如下:
/**
* 使用了 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,返回结果如下所示:
需要清楚的是,@ControllerAdvice 和 @RestControllerAdvice 是应用于对Spring MVC中的控制器抛出的异常进行处理,而对于404这样不会进入控制器处理的异常不起作用,所以此时还是要依靠ErrorController来处理。
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/25642.html