【Spring Boot】Spring Boot 统一功能处理

news2025/1/16 1:47:41

文章目录

  • Spring拦截器
    • 为何需要Spring拦截器?
    • 自定义拦截器
    • 加入系统配置并配置拦截规则
    • 验证登陆拦截器
  • 添加统一访问前缀
    • 验证统一前缀是否添加成功
  • 统一异常处理
  • 统一数据返回格式

Spring拦截器

为何需要Spring拦截器?

在之前Servlet开发中,对登陆校验有两种方法:

  1. 在每个方法中都获取到session中的用户信息,然后判断用户是否存在,如果用户存在则登陆,如果用户不存在则未登陆
  2. 提供统一的方法验证用户是否登陆,在需要验证用户登陆的地方调用该方法进行判断

从上述可以看出这样做比较复杂,因为如果有许多地方需要进行登陆验证的话,就需要写重复的校验代码或者重复调用判断登陆的方法

对此我们提供Spring拦截器来实现用户的统一登陆验证,拦截器的实现分为以下两个步骤:

  1. 创建自定义拦截器类,实现HandlerInterceptor接口并重写preHandle方法
  2. 创建配置类,将自定义的拦截器添加到该配置类中,并添加拦截规则
    • 给配置类添加@Configuration注解
    • 实现WebMvcConfigurer接口
    • 重写addInterceptors方法

注意:一个项目中可以配置多个拦截器

自定义拦截器

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        if(session != null && session.getAttribute("user") != null){
            return true;
        }
        return false;
    }
}

preHandle方法的返回值为boolean类型:

  • 如果返回值为true,表示通过拦截,可以访问后续接口
  • 如果返回值为false,表示拦截未通过,直接返回结果给前端

如果返回为false,前端展示的为空白,对于登陆校验,当拦截未通过时,我们希望返回到登陆界面,所以可以在返回false之前重定向到登陆页面

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        if(session != null && session.getAttribute("user") != null){
            return true;
        }
        //当代码进行到这一步时,说明拦截未通过,防止前端显示空白,重定向到登陆页面
        response.sendRedirect("/login.html");
        return false;
    }
}

加入系统配置并配置拦截规则

@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).
                addPathPatterns("/**"). //拦截所有url
                excludePathPatterns("/user/login"). //排除登陆接口
                excludePathPatterns("/user/register"). //排除注册接口
                //排除所有的静态页面
                excludePathPatterns("/login.html").
                excludePathPatterns("/register.html").
                excludePathPatterns("/**/*.js").
                excludePathPatterns("/**/*.css").
                excludePathPatterns("/**/*.jpg");
    }
}

说明:addPathPatterns表示需要拦截的URL,excludePathPatterns表示需要排除的URL

验证登陆拦截器

  1. 先创建login.html和content.html页面,然后创建后端接口
    @RequestMapping("/login")
    public String login(String username, String password, HttpServletRequest req){
        if(username==null || password==null){
            return "请输入用户名和密码";
        }
        if(username.equals("abc") && password.equals("123")){
            HttpSession session = req.getSession(true);
            session.setAttribute("user","user");
            return "登陆成功";
        }
        return "登陆失败";
    }

    @RequestMapping("/content")
    public String content(){
        return "已经登陆成功";
    }
  1. 创建拦截器(与上述相同,去掉重定向的那行代码),配置拦截规则:我们排除对登陆页面和登陆接口的拦截
@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).
                addPathPatterns("/**"). //拦截所有url
                excludePathPatterns("/user/login"). //排除登陆接口
                excludePathPatterns("/login.html");
    }
}
  1. 启动程序访问登陆页面,登陆页面正常访问
    在这里插入图片描述
  2. 访问登陆接口,正常访问,此时未登陆
    在这里插入图片描述
  3. 在未登录的情况下访问content.html,可以看到显示空白说明拦截器拦截成功
    在这里插入图片描述
  4. 在未登录的情况下访问content接口,可以看到显示空白,说明拦截成功
    在这里插入图片描述
  5. 我们进行登陆后再访问content页面和content接口
    在这里插入图片描述
  6. 登陆成功后,访问content页面成功
    在这里插入图片描述
  7. 登陆成功后,访问content接口成功
    在这里插入图片描述

经过上述步骤,我们的登陆拦截器验证成功,满足我们需求

添加统一访问前缀

给所有的请求url添加前缀

  1. 添加方式一:在配置拦截规则的配置类中重写configurePathMatch方法
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        //c -> true意思是给所有的controller都添加api前缀
        configurer.addPathPrefix("api",c -> true);
    }
  1. 添加方式二:在application配置文件中添加,该方式是给全局添加访问前缀,包括访问html静态文件
server:
  servlet:
    context-path: /api

验证统一前缀是否添加成功

启动程序,用之前的url访问登陆接口,发现找不到资源

在这里插入图片描述

添加api前缀访问,访问成功

在这里插入图片描述

注意:如果添加了拦截规则,也必须给拦截规则添加前缀,否则会被拦截器拦截到,前端将显示空白

 excludePathPatterns("/api/user/login")

统一异常处理

统一异常的步骤:

  1. 创建一个类,添加@ControllerAdvice注解
  2. 创建一个方法,方法上添加@ExceptionHandler注解

@ControllerAdvice表示当前类是针对controller的通知类(增强类),@ExceptionHandler是异常处理器,两个结合表示当出现异常的时候执行某个通知

//返回json格式数据,将@Controller与@ResponseBody注解合成一个注解@RestController
@RestControllerAdvice
public class MyException {

    @ExceptionHandler(Exception.class)
    public Object handler(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("state",-1);
        map.put("data",null);
        map.put("msg",e.getMessage());
        return map;
    }
}

对异常进行统一处理后,当服务器出现500错误时,会给前端返回自定义的错误信息,不会再直接返回给前端500状态码了

在这里插入图片描述

统一数据返回格式

统一数据返回格式步骤:

  1. 创建一个类,添加@ControllerAdvice注解,实现ResponseBodyAdvice接口
  2. 重写supports和beforeBodyWrite方法
@RestControllerAdvice
public class MyResponse implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        //返回true表示返回数据之前对数据进行重写,也就是会进入beforeBodyWrite方法再返回
        //返回false表示对返回数据不进行任何处理,不会进入beforeBodyWrite方法,直接返回
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        Map<String,Object> result = new HashMap<>();
        result.put("state",1);
        result.put("data",body);
        result.put("message","");
        return request;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/44992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解java虚拟机:虚拟机字节码执行引擎(2)

文章目录3. 方法调用3.1 解析3.2 分派接着深入理解java虚拟机&#xff1a;虚拟机字节码执行引擎&#xff08;1&#xff09;&#xff0c;我们继续往下看&#xff1a; 3. 方法调用 方法调用并不等同于方法执行&#xff0c;方法调用阶段唯一的任务就是确定被调用方法的版本&…

【LeetCode每日一题】——771.宝石与石头

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 字符串 二【题目难度】 简单 三【题目编号】 771.宝石与石头 四【题目描述】 给你一个字符串…

配电网电压调节及通信联系研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

三年城市NOH落地100城,毫末智行内部信剑指2025

11月29日&#xff0c;毫末智行董事长张凯、CEO顾维灏联合发布《毫末智行三周岁&#xff1a;三年磨一剑 利刃开新篇》的内部信&#xff0c;提到毫末愿景及战略目标&#xff1a;“让机器智能移动&#xff0c;给生活更多美好。”未来成长为一家产品矩阵覆盖全无人驾驶、机器人等多…

[附源码]Python计算机毕业设计Django“科教兴国”支教门户网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【毕业设计】26-基于单片机心跳体温血压系统仿真设计(原理图+仿真+演示视频+论文)

【毕业设计】基于单片机心跳体温血压系统仿真设计&#xff08;原理图仿真演示视频论文&#xff09; 文章目录【毕业设计】基于单片机心跳体温血压系统仿真设计&#xff08;原理图仿真演示视频论文&#xff09;任务书设计说明书摘要设计说明书及设计文件任务书 以单片机为控制核…

DPDK helloworld示例程序

目录 helloworld源代码 helloword编译 helloworld代码解析 DPDK的helloworld示例程序&#xff0c;用以示例DPDK应用程序的编写和使用。 helloworld源代码 helloworld代码构成&#xff1a; /* 省略系统头文件*//* DPDK相关的rte头文件 */ #include <rte_memory.h>…

springboot 集成JWT实现token验证

JWT介绍 是一种开放标准 &#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且独立的方式&#xff0c;用于将信息作为 JSON 对象在各方之间安全地传输。该信息可以进行验证和信任&#xff0c;因为它是经过数字签名的。JWT 可以使用密钥&#xff08;使用 HMAC 算法…

拾忆书苑(图书商城系统)网站的设计与实现(html;DIV+CSS; Bootstrap; Dreamweaver; Photoshop)

目 录 一、绪论 1 &#xff08;一&#xff09;课题研究背景 1 &#xff08;二&#xff09;课题研究目的及意义 1 二、相关技术与工具介绍 1 &#xff08;一&#xff09;Dreamweaver开发技术 1 &#xff08;二&#xff09;Adobe Photoshop 1 三、拾忆书店网站的设计与分析 2 &am…

某村庄供水工程设计(设计报告+cad图纸+预算工程量清单)

目 录 工程特性表 1 1 综合说明 3 1.1 工程背景 3 1.2 设计依据 3 1.3 工程建设的必要性与可行性 3 1.4 供水范围、规模及水源选择 4 1.5 工程总体布置 4 1.6 工程设计 4 1.7 工程施工 5 1.8 工程管理 5 1.9 预算 5 2 项目区概况及项目建设的必要性 6 2.1 项目区自然概况 6 2.2…

Head First设计模式(阅读笔记)-06.命令模式

家电自动化遥控器 假设要创建一个遥控器&#xff0c;该遥控器上有7个插槽(每个可以插上不同的家电)&#xff0c;每个插槽对应了开关按钮&#xff0c;并且遥控器上还有一个撤销按钮用于撤销上一次的操作 从餐厅点餐开始 假设一个顾客来到餐厅要进行点餐&#xff0c;整体流程如下…

不用ps怎么修改图片?电脑图片在线处理的方法

很多小伙伴在工作、学习的时候会用到简单的图片处理工具&#xff08;在线ps 图片编辑制作工具 免费照片编辑器_压缩图&#xff09;&#xff0c;但是因为用到的功能比较多&#xff0c;需要下载安装很多电脑处理图片软件&#xff0c;非常不方便&#xff0c;而且上手比较难。下面就…

【学习笔记53】JavaScript正则表达式练习题

正则表达式练习题一、用户名、密码和手机号的验证1、案例要求2、案例分析3、HTML和CSS代码4、JS代码二、密码强度1、案例要求2、案例分析3、HTML和CSS代码4、JS代码的实现三、书写正则验证邮箱1、邮箱的验证2、代码的实现四、书写正则验证0~255的数字一、用户名、密码和手机号的…

global关键字、python实现ATM简单功能

目录 一.局部变量、全局变量 二.global关键字 演示 三.编写ATM程序 要求 详细步骤 存在问题 改进 完整代码 一.局部变量、全局变量 1.什么是局部变量 作用范围在函数内部&#xff0c;在函数外部无法使用 2.什么是全局变量 在函数内部和外部均可使用 3.如何将函数内定…

Nature子刊:精准预测分子性质和药物靶标的无监督学习框架

药品的临床疗效与安全性由在人类蛋白质组内的分子靶标决定。本文中&#xff0c;湖南大学信息科学与工程学院的李肯立/曾湘祥教授课题组提出了一种无监督的预训练深度学习框架&#xff0c;对 1000 万个未标记的类药性、生物活性分子进行预训练&#xff0c;以预测候选化合物的药物…

osgEarth示例分析——osgearth_manip

前言 本示例主要演示osgEarth的事件处理的用法&#xff0c;内容比较多&#xff0c;这部分功能也很重要。 输入命令依然采用china-simple.earth的示例&#xff0c;加上了模型&#xff0c;但是模型并没有看到&#xff0c;可能是因为模型没有放大太小的原因。在代码中设置了不加…

传奇单机架设登录器配置教程

传奇单机顾名思义就是在本地电脑上架设传奇&#xff0c;限制同一个局域网才能一起玩&#xff0c;我接触到几个朋友不明白外网和单机的区别 架设单机需要准备以下程序&#xff1a; 传奇服务端&#xff08;版本Mirserver&#xff09; DBC2000 (百度可直接下载&#xff09; 配套登…

IPv6进阶:IPv6 过渡技术之 GRE 隧道

实验拓扑 R1-R3-R2之间的网络为IPv4环境PC1及PC2处于IPv6孤岛 实验需求 R1及R2为IPv6/IPv4双栈设备在R1及R2上部署GRE隧道使得PC1及PC2能够互相访问&#xff08;先采用IPv6静态路由实现互通&#xff09;R1及R2基于建立好的GRE隧道运行OSPFv3交互IPv6路由前缀 实验步骤及配置…

【数据可视化】免费开源BI工具 DataEase 之 Tab 组件前世今生

小D &#xff1a;小助理&#xff0c;小助理&#xff0c;在哪儿呢&#xff1f;&#xff08;焦急脸&#xff09; BI 小助理&#xff1a;在呢&#xff0c;啥事&#xff1f;&#xff08;不耐烦脸&#xff09; 小D &#xff1a;又有 BI 工具放大招啦&#xff01;&#xff01;&…

C语言习题练习11--指针

1.代码结果 #include <stdio.h> int main() {int arr[] {1,2,3,4,5};short *p (short*)arr;int i 0;for(i0; i<4; i){*(pi) 0;}for(i0; i<5; i){printf("%d ", arr[i]);}return 0; } 正常&#xff1a;0001--00 02--00 03--00 04--00 05 数组内部是倒…