【SpringBoot+MyBatisPlus】系统全局异常处理器的使用以及添加员工功能的实现

简介: 系统全局异常处理器的使用以及添加员工功能的实现

前言

承接上文,设计完了登录与退出功能还只完成了冰山一角,经过测试发现,我们以url的方式来访问网站时可以直接跳过登陆页面进入后台页面,这样显然是不合理的,下面我们通过拦截器+boot来做到访问限制,以及实现新增员工功能,制作全局异常处理器

一.完善登录功能

按照常理,只有登陆过后才能进入首页,若没有登陆则应当直接跳转到登陆页面,这样的场景不就完美契合过滤器的功效吗

下面,针对此功能来设计一个过滤器

@Slf4j
@WebFilter(filterName = "loginFilterCheck", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        log.info("拦截到请求:{}", request.getRequestURI());//{}相当于一个占位符 可以实现动态变更
        filterChain.doFilter(request,response);
    }
}

通过它可以拦截到来自页面的请求
在这里插入图片描述
对于拦截的请求,我们要做如下的处理:
在这里插入图片描述
1、获取本次请求的URI,并定义不需要放行的资源路径

        //获取本次请求的uri
        String requestURI = request.getRequestURI();

        //定义不需要处理的资源路径
        String[] urls=new String[]{
          "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };

为了解决通配符的引入而造成的路径比较问题,我们可以通过路径匹配器AntPathMatcher()来解决(由Spring为我们提供的工具)
在这里插入图片描述
2、判断本次请求是否需要处理
当我们拿到工具对象之后,就可以通过遍历字符串数组的方式,将请求中的uri与事先设定中不需要拦截资源路径进行对比,然后封装成一个check方法,就像这样:

    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match){
                return true;
            }
        }
        return false;
    }

3.如果是不需要处理的资源路径则直接放行

        //判断是否需要处理
        boolean check = check(urls, requestURI);
        //如果不需要处理就直接放行
        if (check){
            filterChain.doFilter(request,response);
            return;
        }

4、判断登录状态,如果已登录,则直接放行,如果未登录则返回未登录结果(通过从Session里获得对象,查看是否为空来进行评判)

        //查看登陆状态 如果已登录 则直接放行
        if (!(request.getSession().getAttribute("employee") == null)) {
            filterChain.doFilter(request, response);
            return;
        }
        //如果未登录,则通过输出流的方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));

二.添加员工功能

前端页面已将写好,,当用户录入信息,就伴随着一次请求,而后端要做的就是将在请求中将表单里的数据保存到数据库中
新增员工,其实就是将我们添加页面录入的员工数据插入到employee表。需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账号,必须是唯一的
在这里插入图片描述
我们该如何实现?
在这里插入图片描述

**1、当页面发送ajax请求,表单中输入的数据以json的形式提交到服务器端
2、服务端Controller层接收页面提交的数据并调用Service层将数据进行保存
3、Service调用Mapper操作数据库,保存数据**

Controller层如何设计呢?
1.毋庸置疑的是,首先要封装一个用于保存的方法save()
2.其次HttpServletRequest里已经封装了表单的数据,当一次请求发生其中的数据就被当作形参传入了方法内,随即就是设置表单中没有的属性,比如:setCreateTime,setUpdateTime,setCreateUser,setUpdateUser
总而言之,方法里涵盖了表单里提交的数据和请求发生后动态变更的数据,而我们写好了save()方法之后,就得去用Service层(employeeService)来执行这个方法将数据保存到数据库中,就像这样:

    @PostMapping //前端的请求路径为employee,而上述@RequestMapping("/employee")已写好
    public R<String> save(HttpServletRequest request, @RequestBody Employee employee) {
        log.info("新增员工:{}", employee.toString());
        //设置初始默认密码
       employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        //设置更新时间
        employee.setCreateTime(LocalDateTime.now());//创建时间
        employee.setUpdateTime(LocalDateTime.now());//更新时间
        //获取当前登录用户的id
        Long empID = (Long) request.getSession().getAttribute("employee");
        employee.setCreateUser(empID);
        employee.setUpdateUser(empID);
        
        return R.success("添加员工成功!");
    }

当我们在前端表单中填好了新增员工的信息后,点击保存,后台就执行如下的SQL:
在这里插入图片描述

三.异常处理的运用

写好了添加的方法,我激动得添加了好几个员工,但是当我添加了一个同名员工之后,程序运行的戛然而止,后台竟然抛出了异常:java.sql.SQLIntegrityConstraintViolationException
前端也报出了接口错误500,结合之前的表设计,不难想到我的username索引设置的是unique呀!唯一约束!

很显然
我们需要处理这个异常,很多人第一时间想到的可能是:这则错误是service层调用save()方法所导致的,那我把save()方法try-catch不就行了吗?
在这里插入图片描述
这样想确实没毛病是我的话我也这样,可是以后业务一旦复杂起来,需要这样处理的方法多了怎么办呢?我要去一个一个try-catch吗?多麻烦啊!
这不就是所谓的硬编码问题嘛!处理这种问题咱们在一个地方统一配置一下不久统统解决啊,跟MyBatis解决JDBC硬编码问题是一个道理!

所以,我们使用异常拦截器进行全局异常捕获,这样设置就轻松化解:

/**
 * 全局异常处理
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class}) //拦截有指定注解类的Controller
@Slf4j
@ResponseBody
public class GlobalExceptionHandler {
    /**
     * 异常处理方法,一旦Controller发生此异常就会被拦截到
     * @return
     */
    @ExceptionHandler({SQLIntegrityConstraintViolationException.class})
    public R<String>  excpHandler(SQLIntegrityConstraintViolationException exception) {//捕获到的异常被传到方法的形参里
       log.info("异常信息:"+exception.getMessage());
        //细化添加失败后的返回信息
        if (exception.getMessage().contains("Duplicate entry")){
            String[] s = exception.getMessage().split(" ");
            String msg=s[2]+"已存在!";
            return R.error(msg);
        }
        return R.error("发生异常!添加失败!");
    }
}

一旦Controller层发生此异常就会被拦截到!
在这里插入图片描述
通过Debug,当程序出现因为重复添加而引起的异常时我们的msg就被细化了出来
在这里插入图片描述

相关文章
|
20天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
36 4
|
22天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
113 1
|
17天前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
28 0
|
6天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
84 62
|
1天前
|
SQL Java 数据库连接
深入 MyBatis-Plus 插件:解锁高级数据库功能
Mybatis-Plus 提供了丰富的插件机制,这些插件可以帮助开发者更方便地扩展 Mybatis 的功能,提升开发效率、优化性能和实现一些常用的功能。
50 26
深入 MyBatis-Plus 插件:解锁高级数据库功能
|
2天前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
29 8
|
24天前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
70 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
4天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
14 2
|
24天前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
39 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
6天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。