告别try catch,SpringBoot优雅的全局异常处理机制
近期在基于sa-token做一套基础框架,正好其中用到了全局异常处理,发现没有整理到笔记本里,特别给大家分享下,介绍一下我们 Spring 项目必备的全局处理 Controller 层异常。
相关注解:
-
@ControllerAdvice
:注解定义全局异常处理类 -
@ExceptionHandler
:注解声明异常处理方法
如何使用呢?拿我们在第 5 节参数校验这块来举例子。如果方法参数不对的话就会抛出MethodArgumentNotValidException
,我们来处理这个异常。
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
/**
* 请求参数异常处理
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
......
}
}
**@RestControllerAdvice **
就是@ControllerAdvice和@ResponseBody整合后的注解
更多关于 Spring Boot 异常处理的内容,请看我的这两篇文章:
以混沌(hudn)项目为例,对应的开源项目地址:https://gitee.com/yunhoio/hudn
定义全局异常类
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
// 全局异常拦截(拦截项目中的所有异常)
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult handler500Exception(Exception e)
throws Exception {
// 打印堆栈,以供调试
log.error("全局异常信息 ex={}",e.getMessage(),e);
// 返回给前端
return ResponseResult.failed(e.getLocalizedMessage());
}
@ExceptionHandler(NotLoginException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public ResponseResult handlerNotLoginException(NotLoginException e){
log.error("未登录,请登录后再次访问 ex={}",e.getMessage(),e);
return ResponseResult.failed("未登录,请登录后再次访问");
}
@ExceptionHandler(NotRoleException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ResponseResult handlerNotRoleException(NotRoleException e){
log.error("拒绝授权异常信息,无此角色 role={} ex={}",e.getRole(),e.getMessage(),e);
return ResponseResult.failed("拒绝授权异常信息,无此角色");
}
@ExceptionHandler(NotPermissionException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ResponseResult handlerNotPermissionException(NotPermissionException e){
log.error("拒绝授权异常信息,无此权限 code={} ex={}",e.getCode(),e.getMessage(),e);
return ResponseResult.failed("拒绝授权异常信息,无此权限");
}
@ExceptionHandler(DisableLoginException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ResponseResult handlerDisableLoginException(DisableLoginException e){
log.error("拒绝授权异常信息,账号被封禁 msg={} ex={}",e.getDisableTime()+"秒后解封",e.getMessage(),e);
return ResponseResult.failed("拒绝授权异常信息,账号被封禁 "+e.getDisableTime()+"秒后解封");
}
}
模拟异常
@RestController
@RequestMapping("/auth")
public class IndexController {
@GetMapping("/index")
public String index(){
throw new RuntimeException("exception hello ");
// return "auth hello world";
}
}
测试
访问:http://localhost:8080/auth/index
异常:
{"code":0,"msg":"exception hello ","data":null}
可能出现的问题
问题:可能出现不生效的情况
原因:因为springboot的加载机制,启动类会默认扫描当前包名,如果全局异常处理类不在当前路径就会无法加载上,需要处理一下扫描包的范围
@SpringBootApplication(scanBasePackages = "io.yunho.*")
@EnableDiscoveryClient
public class AuthServerStarter {
public static void main(String[] args) {
SpringApplication.run(AuthServerStarter.class, args);
System.out.println("nSa-Token-SSO 认证中心启动成功");
System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
}
}
原文始发于微信公众号(云户):告别try catch,SpringBoot优雅的全局异常处理机制
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/35270.html