小菜家教平台(四):基于SpringBoot+Vue打造一站式学习管理系统

news/2024/11/8 9:50:05 标签: 学习

前言

昨天配置完了过滤器,权限检验,基本的SpringSecurity功能已经配置的差不多了,今天继续开发,明天可能会暂停一天整理一下需求,然后就进行CRUD了。

 

今日进度

补充SpringSecurity异常处理和全局异常处理器

详细操作

一、补充SpringSecurity异常处理器

当我们没有进行异常处理,项目如果出现了问题,我们很难排查,同时进行异常处理后,返回的数据就比较有规范,可以让前端的开发看懂。

比如我们现在使用一个错误的密码进行登录,Apifox显示403,这对吗?不太对,因为403是用户未授权,而我们这里是认证的问题,应该返回401才正确。这就导致今天检查的时候找了好久,最后才发现是密码写错了,如果返回信息是401,那不是就很快就发现问题了。因此,异常处理还是很重要的。

在SpringSecurity中,如果我们在认证或者授权的过程中出现了异常会被ExceptionTranslationFilter捕获到。在ExceptionTranslationFilter中会去判断是认证失败还是授权失败出现的异常。

​ 如果是认证过程中出现的异常会被封装成AuthenticationException然后调用AuthenticationEntryPoint 对象的方法去进行异常处理,返回401。

​ 如果是授权过程中出现的异常会被封装成AccessDeniedException然后调用AccessDeniedHandler对象的方法去进行异常处理,返回403。

​ 所以如果我们需要自定义异常处理,我们只需要自定义AuthenticationEntryPoint和AccessDeniedHandler然后配置给SpringSecurity即可。

听上去听复杂的?但是实现并不复杂

只要重写AuthenticationException和AccessDeniedHandler方法并添加到配置中即可。

@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        ResponseResult result = new ResponseResult(HttpStatus.UNAUTHORIZED.value(), "用户认证失败,请重新登录");
        String json = JSON.toJSONString(result);
        WebUtils.renderString(response,json);
    }
}
@Component
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        ResponseResult result = new ResponseResult(HttpStatus.FORBIDDEN.value(), "权限不足");
        String json = JSON.toJSONString(result);
        WebUtils.renderString(response,json);
    }
}
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //关闭csrf
                .csrf().disable()
                //不通过Session获取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 对于登录接口 允许匿名访问
                .antMatchers("/user/login").anonymous()
                .antMatchers("/hello/**").hasRole("ADMIN")//对于/hello的路径,只有ADMIN权限的用户才能访问
                .antMatchers("/ok/**").hasAnyRole("ADMIN","TEACHER")//对于/ok的路径,ADMIN和USER权限的用户都可以访问
                // 除上面外的所有请求全部需要鉴权认证
                .anyRequest().authenticated();

        //添加自定义过滤器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //添加自定义异常处理
        http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);
    }

这样,我们进行测试就能很快的发现问题了,如下图:

二、全局异常处理

上面我们只进行了有关SpringSecurity的异常处理,那要是其他地方出现异常怎么办?所以我们要进行全局的异常处理。因为项目不太大,所以这里使用了一个简单的全局异常处理,要是后面项目实现功能很多的话,可以考虑使用复杂完整的全局异常处理。

首先,为了进行测试,我们先编写两个异常方法,一个是数组越界,一个是除0

@RequestMapping("/ok/t1")
    public int test1(){
        List<Integer> integers = new ArrayList<>();
        for (int i = 0; i < 10; i++){
            integers.add(i);
        }
        //故意数组过界进行异常测试
        for (int i = 0; i < 20; i++){
            System.out.println(integers.get(i));
        }
        return 1;
    }

    @RequestMapping("/ok/t2")
    public int test2(){
        int t = 10/0;
        System.out.println(t);
        return 1;
    }

接着编写一下全局异常类

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 捕获所有的 RuntimeException 异常
    @ExceptionHandler(value = {RuntimeException.class})
    public ResponseResult<String> handleRuntimeException(RuntimeException e) {
        // 这里会捕获到一些业务异常,或者其他运行时异常
        return new ResponseResult<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "运行时异常: " + e.getMessage());
    }

    // 捕获所有其他的 Exception 异常
    @ExceptionHandler(value = {Exception.class})
    public ResponseResult<String> handleException(Exception e) {
        // 处理一些无法捕获的异常
        return new ResponseResult<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常: " + e.getMessage());
    }
}

并在统一返回信息中添加一个方法

public static ResponseResult<String> error(String message){
        return new ResponseResult<>(500,message,null);
    }

这样就行了,是不是很简单。接下来进行测试。

密码错误:

权限异常:

数组越界:

除零:

这样项目中的异常就可以成功处理了,但是有没有发现一个小问题:

我们原先配置的SpringSecurity中的认证异常被全局异常覆盖了,但是权限异常还是SpringSecurity中我们配置的异常。

这里暂时不会出问题,就是返回的信息看上去与全局异常无关联,不整齐,我们修改一下权限异常处理即可。但是我认为这里应该有更好的处理方法,也可能是我的全局异常处理过于简单导致的,如果有大佬看到这里还请指点一下~

总结

今天首先通过自定义AuthenticationEntryPointAccessDeniedHandler实现了认证与授权失败的异常捕获,返回适当的状态码。随后,介在项目中实现全局异常处理,捕获运行时异常和系统异常,并统一处理返回。这样,不仅提高了系统的可维护性,还能帮助开发人员快速定位问题并保证前后端的异常响应一致性。

那今天就这样,明天可能暂停一天,整理一下url路径、返回数据等一些与业务相关的内容。如果这篇文章有帮到你的话,还希望多多支持,你的支持就是我的最大动力!


http://www.niftyadmin.cn/n/5743705.html

相关文章

从0开始学习机器学习--Day18--评估模型

在很多时候&#xff0c;构建并优化完模型并不代表这个问题就被解决了。事实上&#xff0c;很多时候&#xff0c;在第一次优化结束并进行预测时&#xff0c;其与真实值之间的误差都会提醒你这个模型需要继续优化。那么&#xff0c;我们应该怎么优化它呢&#xff1f; 选择更多的…

R 语言科研配色 --- 第 11 期

在使用 R 语言进行科研绘图时&#xff0c;颜色的选择是一件让人特别纠结的事情。本系列文章介绍了 R 语言科研绘图时常用的一些配色。 为了便于使用&#xff0c;本系列文章介绍的所有配色都已收录到了 sciRcolor 项目中&#xff0c;获取方式&#xff1a; R 语言科研配色工具 …

安装和运行开发微信小程序

下载HBuilder uniapp官网 uni-app官网 微信开发者工具 安装 微信小程序 微信小程序 官网 微信小程序 配置 运行 注意&#xff1a;运行前需要开启服务端口 如果运行看不到效果&#xff0c;设置下基础库选别的版本 配置

Python与Excel交互:pandas库安装及基本用法

在之前的文章中&#xff0c;我们探讨了Python处理Excel文件的基本概念&#xff0c;如工作簿、工作表以及单元格等。现在我们将转向具体的工具介绍——pandas库&#xff0c;它是Python中最常用的数据分析库之一&#xff0c;能够非常便捷地读取、处理和写入Excel文件。 安装pand…

Jenkins声明式Pipeline流水线语法示例

系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline&#xff1f;1.2、为什么使用pi…

centos7,yum安装mongodb

yum安装mongodb 1.配置MongoDB的yum源2.安装Mongodb3.启动Mongodb4.配置远程访问5.设置mongo密码 1.配置MongoDB的yum源 1.创建yum源文件&#xff0c;输入命令&#xff1a; vim /etc/yum.repos.d/mongodb-org-5.0.repo然后在文件中输入以下内容并保存&#xff1a; [mongodb-…

HashMap底层原理(jdk1.7和jdk1.8对比)?

HashMap 底层结构与实现 HashMap 底层是基于哈希表&#xff08;Hash Table&#xff09;实现的&#xff0c;它存储的元素是键值对&#xff08;key-value&#xff09;。底层的数据结构是一个数组&#xff0c;数组的每个元素是一个 桶&#xff08;bucket&#xff09;&#xff0c;…

5G周边知识笔记

这里写目录标题 3GPP 5G标准路径图5G协议规范5G新空口关键指标4G LTE和5G NR新空口技术对比5G新频段FR1FR2 信道带宽上下行解耦新频点规划&#xff0c;信道栅格FR1各频段实际信道栅格和NR-ARFCN范围定义 同步栅格大规模天线阵列新型调制编码技术大规模载波聚合设备到设备直接通…