SpringBoot 统一功能处理:用户登录权限校验-拦截器、异常处理、数据格式返回 下

简介: SpringBoot 统一功能处理:用户登录权限校验-拦截器、异常处理、数据格式返回 下

2. 统一异常处理

给当前的类上加 @ControllerAdvice 表示控制器通知类

给方法上添加 @ExceptionHandler(xxx.class),表示异常处理器,添加异常返回的业务代码

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/index")
    public String index() {
        int num = 10/0;
        return "Hello Index";
    }
}

在 config 包中,创建 MyExceptionAdvice

@RestControllerAdvice // 当前是针对 Controller 的通知类(增强类)
public class MyExceptionAdvice {
    @ExceptionHandler(ArithmeticException.class)
    public HashMap<String,Object> arithmeticExceptionAdvice(ArithmeticException e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("state",-1);
        result.put("data",null);
        result.put("msg" , "算出异常:"+ e.getMessage());
        return result;
    }
}

也可以这样写,效果是一样的

@ControllerAdvice
public class MyExceptionAdvice {
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public HashMap<String,Object> arithmeticExceptionAdvice(ArithmeticException e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("state",-1);
        result.put("data",null);
        result.put("msg" , "算数异常:"+ e.getMessage());
        return result;
    }
}

image.png

如果再有一个空指针异常,那么上面的代码是不行的,还要写一个针对空指针异常处理器

@ExceptionHandler(NullPointerException.class)
public HashMap<String,Object> nullPointerExceptionAdvice(NullPointerException e) {
    HashMap<String, Object> result = new HashMap<>();
    result.put("state",-1);
    result.put("data",null);
    result.put("msg" , "空指针异常异常:"+ e.getMessage());
    return result;
}
@RequestMapping("/index")
public String index(HttpServletRequest request,String username, String password) {
    Object obj = null;
    System.out.println(obj.hashCode());
    return "Hello Index";
}

image.png

但是需要考虑的一点是,如果每个异常都这样写,那么工作量是非常大的,并且还有自定义异常,所以上面这样写肯定是不好的,既然是异常直接写 Exception 就好了,它是所有异常的父类,如果遇到不是前面写的两种异常,那么就会直接匹配到 Exception

当有多个异常通知时,匹配顺序为当前类及其⼦类向上依次匹配

@ExceptionHandler(Exception.class)
public HashMap<String,Object> exceptionAdvice(Exception e) {
    HashMap<String, Object> result = new HashMap<>();
    result.put("state",-1);
    result.put("data",null);
    result.put("msg" , "异常:"+ e.getMessage());
    return result;
}

可以看到优先匹配的还是前面写的 空指针异常

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

3. 统一数据格式返回

3.1 统一数据格式返回的实现

1.给当前类添加 @ControllerAdvice

2.实现 ResponseBodyAdvice 重写其方法

  • supports 方法,此方法表示内容是否需要重写(通过此⽅法可以选择性部分控制器和方法进行重写),如果要重写返回 true
  • beforeBodyWrite 方法,方法返回之前调用此方法
@ControllerAdvice
public class MyResponseAdvice implements ResponseBodyAdvice {
    // 返回一个 boolean 值,true 表示返回数据之前对数据进行重写,也就是会进入 beforeBodyWrite 方法
    // 返回 false 表示对结果不进行任何处理,直接返回
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }
    // 方法返回之前调用此方法
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        HashMap<String,Object> result = new HashMap<>();
        result.put("state",1);
        result.put("data",body);
        result.put("msg","");
        return result;
    }
}
@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public boolean login(HttpServletRequest request,String username, String password) {
        boolean result = false;
        if (StringUtils.hasLength(username) && StringUtils.hasLength(password)) {
            if(username.equals("admin") && password.equals("admin")) {
                HttpSession session = request.getSession();
                session.setAttribute("userinfo","userinfo");
                return true;
            }
        }
        return result;
    }
    @RequestMapping("/reg")
    public int reg() {
        return 1;
    }
}

image.png

3.2 @ControllerAdvice 源码分析

通过对 @ControllerAdvice 源码的分析我们可以知道上面统一异常和统一数据返回的执行流程

(1)先看 @ControllerAdvice 源码

可以看到 @ControllerAdvice 派生于 @Component 组件而所有组件初始化都会调用 InitializingBean 接口

(2)下面查看 initializingBean 有哪些实现类

在查询过程中发现,其中 Spring MVC 中的实现子类是 RequestMappingHandlerAdapter,它里面有一个方法 afterPropertiesSet()方法,表示所有的参数设置完成之后执行的方法

(3)而这个方法中有一个 initControllerAdviceCache 方法,查询此方法

发现这个方法在执行时会查找使用所有的 @ControllerAdvice 类,发送某个事件时,调用相应的 Advice 方法,比如返回数据前调用统一数据封装,比如发生异常是调用异常的 Advice 方法实现的



相关文章
|
3月前
|
消息中间件 缓存 Java
手写模拟Spring Boot启动过程功能
【11月更文挑战第19天】Spring Boot自推出以来,因其简化了Spring应用的初始搭建和开发过程,迅速成为Java企业级应用开发的首选框架之一。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,帮助读者深入理解其工作机制。
64 3
|
3月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
79 0
|
3月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
222 8
|
3月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
231 2
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。
61 10
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的家政服务管理平台设计与实现(计算机毕设项目实战+源码+文档)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
46 8
|
26天前
|
JavaScript 搜索推荐 Java
基于SpringBoot+Vue实现的家乡特色推荐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 8
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的高校食堂移动预约点餐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
70 3
|
26天前
|
JavaScript NoSQL Java
基于SpringBoot+Vue实现的冬奥会科普平台设计与实现(系统源码+文档+数据库+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
45 0
|
26天前
|
JavaScript NoSQL Java
基于SpringBoot+Vue实现的大学生体质测试管理系统设计与实现(系统源码+文档+数据库+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
38 2