告别try catch,SpringBoot优雅的全局异常处理机制


告别try catch,SpringBoot优雅的全局异常处理机制


近期在基于sa-token做一套基础框架,正好其中用到了全局异常处理,发现没有整理到笔记本里,特别给大家分享下,介绍一下我们 Spring 项目必备的全局处理 Controller 层异常。

相关注解

  1. @ControllerAdvice :注解定义全局异常处理类
  2. @ExceptionHandler :注解声明异常处理方法

如何使用呢?拿我们在第 5 节参数校验这块来举例子。如果方法参数不对的话就会抛出MethodArgumentNotValidException,我们来处理这个异常。

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * 请求参数异常处理
     */

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException exHttpServletRequest request
{
       ......
    }
}

**@RestControllerAdvice **

就是@ControllerAdvice和@ResponseBody整合后的注解

更多关于 Spring Boot 异常处理的内容,请看我的这两篇文章:

  1. SpringBoot 处理异常的几种常见姿势
  2. 使用枚举简单封装一个优雅的 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.classargs);
        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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!