增删改查基础项目总结

    上篇中主要负责后端部分完成了一个简单的学习辅助系统部分界面,主要针对增删改查进行了练习,过程中遇到了一些细节上的问题以及当时做的时候去查阅的一些之前没有太注意到的额外知识,所以还需要进行进一步梳理,像登录校验的方法以及cookie、session、jwt的区别和联系以及Filter和Interceptor区别和使用方式等。(学习辅助系统)

目录

1.环境搭建

2.登陆校验(重要)

2.1 会话技术

①cookie

②session

③令牌技术

3.过滤器Filter

4.拦截器 Interceptor


1.环境搭建

一个简单的单体架构项目,对于后端部分来说,首先需要进行环境搭建,准备好数据库表,然后创建springboot工程,引入相应的起步依赖,然后在配置文件中引入相应的配置信息(mybatis mysql等)。前端、后端、数据库整体关系如下图所示:

在yml配置文件中有一些需要注意的地方,很容易出现错误,如下图所示:

这里简单介绍一下@Value和@ConfigurationProperties注解的区别:

@ConfigurationProperties注解可以批量注入配置文件中的属性,支持松散绑定(松散语法),不支持SpEL,支持JSR303数据校验和复杂类型封装。

@Value注解需要一个个指定,支持三种取值方式,分别是 字面量、${key}从环境变量、配置文件中获取值以及 #{SpEL},不支持松散绑定(松散语法)、JSR303数据校验和复杂类型封装,支持SpEL。

松散语法的意思就是一个属性在配置文件中可以有多个属性名。

SpEL 使用 #{…} 作为定界符 , 所有在大括号中的字符都将被认为是 SpEL , SpEL 为 bean 的属性进行动态赋值提供了便利。

复杂类型封装指的是,在对象以及 map (如学生类中的老师类以及 scores map)等属性中,用 @Value 取是取不到值

2.登陆校验(重要)

首先用户登录之后会存一个登陆标记,然后在每一次发送请求之后会进行统一拦截,取出登陆标记,如果可以取出的话说明用户已经登陆了,所以可以直接放行,对于没有标记的需要进行拦截,无法跳转到对应界面。

登录校验的四种方法:

下面两种是用于跟踪:1、会话技术2、JWT令牌

下面两个是用于拦截校验的,可以进行Jwt令牌校验:3、过滤器Filter 4、拦截器Interceptor

2.1 会话技术

下面的请求1,2,3是同一个浏览器发出的,所以是同一个会话,可以进行共享数据;但是采用http协议时,该协议每次请求都是独立上一个请求和下一个请求没有联系,所以两次请求不知道是否是一个浏览器发出的,该协议效率比较高,但是不好确定是否是同一会话从而进行共享数据,所以要用到会话跟踪方案(会话跟踪是一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一个浏览器,确保同一次会话之间的请求可以共享数据。)

①cookie

Cookie是一段文本数据,在用户完成”身份认证或会话状态更新“后,它会被服务端放在HTTP响应包的Set-Cookie中,并发送给客户端进行保存

会话跟踪:首先客户端发送请求后例如login请求,服务端会设置一个cookie,然后响应数据时会自动连带cookie也发送到客户端,然后客户端会自动保存,然后下次请求的时候会连带这个cookie自动发送给服务端,然后服务端进行检查是否可以检查到cookie相应的值,进而会话跟踪;

cookie的优缺点:

优点:是HTTP协议中支持的技术

缺点:1.移动端APP无法使用cookie 2.cookie存储在客户端,相对来说不安全,并且可以将cookie进行拦截,并且用户可以自己去禁用cookie  3.cookie不能跨域使用

举个例子:浏览器先去访问前端ip为192.168.150.200,端口号为80,此时发送登录请求到服务端ip地址为192.168.150.100,端口号为8080,ip和端口号都不同,说明已经跨域了,此时就不能用cookie了;如下图:

②session

session是基于cookie的,他存储在服务端,相对来说安全一些。

原理:

浏览器第一次请求的时候,服务器里面会进行存储,生成一个sessionID(唯一的),然后通过cookie发送给浏览器。每次访问的浏览器不同的时候,服务器就会进行上面的操作,生成sessionID并且发送给浏览器。当同一个浏览器去访问服务器的时候,由于之前存储过sessionID,因此在登录的时候会把sessionID一起发送给服务器,登录成功之后,就会把身份信息存储到对应的sessionID下面。下次再登录,服务器发现这个sessionID有对应的身份信息,即登录过,就不需要再次登录了。

但是在服务器集群环境下不能直接使用session,后续篇章会介绍点评项目中使用redis代替session解决集群环境下的问题。本身session是基于cookie的,所以一些cookie的缺点也会带过来。

小结:cookie和session都是传统的方案,现在主流的是令牌技术。

③令牌技术

原理:首先浏览器向服务端发送请求,然后此时服务端就会生成一个令牌,然后响应的时候将令牌响应到前端,然后前端会将此令牌存储起来,然后每次发送请求都会将此令牌发送给服务端,然后服务端进行校验,如果令牌是有效的那么就相当于是同一个会话,可以进行共享数据,例如,login请求,然后接着查询请求,先校验令牌成功后说明已经登陆过,无需再登录。

需要自己生成,如何存储,如何携带到服务端需要自己实现。令牌是存储到客户端的,是比较安全的;因为就算篡改了令牌,后面发送请求校验的时候会被检测出来。

JWT令牌:

JWT(Json Web Token)由三个部分组成,第一个部分就是头部,alg是签名算法,type是令牌类型;第二个部分是有效载荷,可以携带自定义的信息;这两个部分都是Json类型的,并且这两部分内容通过Base64编码之后就会用这64个字符来表示内容;第三部分是数字签名,是计算出来的,并不是通过Base64编码得到的,正是有了这个部分保证了安全性。

3.过滤器Filter

 过滤器是javaweb三大组件(Servlet、Filter、Listener)之一,可以把对资源的请求拦截下来,然后进行一些特殊的处理(校验、敏感字符处理等)。

Filter的练习例子:

1.定义Filter:定义一个类,实现Filter接口,然后重写方法

2.配置Filter:Filter类上加@WebFilter注解,配置拦截请求的路径,引导类上加@servletComScan注解开启Servlet组件支持。

整体的逻辑如下图:

Filter路径拦截:在@WebFilter注解中配置

过滤器链:

一个web应用中,可以配置多个过滤器,多个过滤器就构成了过滤器链

注意,注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序。

举个实践的例子:

下面实现了一个简单的登录校验Filter流程:

  1. 首先获取拦截url
  2. 判断url中是否包含login,如果包含,说明是登录请求,此时需要放行。然后服务端生成jwt令牌,然后保存到请求头中。
  3. 获取请求中的令牌(token)
  4. 判断令牌是否存在,如果不存在,返回错误结果 未登录
  5. 如果令牌存在,解析令牌,解析失败返回错误信息。
  6. 放行

具体代码如下:

//过滤器的校验:这个是最先执行的,拦截后的校验,这部分校验后才会执行controller层中的代码;例如,如果是登录请求,此处放行之后才会执行controller层的方法LoginController里面的访问web资源以及生成jwt令牌操作。
@Slf4j
//@WebFilter("/*")
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//在Http协议中使用的是HttpServletRequest,所以要强转一下;HttpServletRequest req=(HttpServletRequest) servletRequest;HttpServletResponse resp=(HttpServletResponse) servletResponse;//1.获取请求urlString url=req.getRequestURL().toString();log.info("请求的url为:"+url);//2.判断请求中是否包含login请求,如果包含说明是登录请求,放行;if(url.contains("login")){log.info("登录请求,放行!");filterChain.doFilter(servletRequest,servletResponse);return;//就不需要执行后面的部分了;}//3.获取请求头token中的令牌String jwt=req.getHeader("token");//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)if(!StringUtils.hasLength(jwt)){log.info("请求头token为空,返回未登录信息!");
//注意,在controller层中有@RestController注解可以将返回的类型转化为json格式,此处并不是controller层并没有这个注解,所以要自己转换,在pom文件中引入一个fastJSON的依赖Result error=Result.error("NOT_LOGIN");String notLogin= JSONObject.toJSONString(error);//这样返回一个json格式的字符串resp.getWriter().write(notLogin);//然后通过resp响应给浏览器return;}//5.解析token,如果解析失败,返回错误结果(未登录)try {JwtUtils.parseJWT(jwt);} catch (Exception e) {//解析失败e.printStackTrace();log.info("解析失败,返回未登陆的错误信息!");Result error=Result.error("NOT_LOGIN");String notLogin=JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return;}//6.放行log.info("令牌合法,放行!");filterChain.doFilter(servletRequest,servletResponse);}
}

4.拦截器 Interceptor

拦截器的实现:

首先定义拦截器,实现HandlerInterceptor接口,并重写所有的方法。

然后在配置类中,添加定义的拦截器,并配置拦截路径:

拦截器路径:

实现案例:

//定义一个拦截器,
@Component
@Slf4j
public class LoginCheckInteceptor implements HandlerInterceptor {@Override//目标资源方法执行前执行,返回true放行,返回false不放行public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {//1.获取请求urlString url=req.getRequestURL().toString();log.info("请求的url为:"+url);//2.判断请求中是否包含login请求,如果包含说明是登录请求,放行;if(url.contains("login")){log.info("登录请求,放行!");return true;}//3.获取请求头token中的令牌String jwt=req.getHeader("token");//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)if(!StringUtils.hasLength(jwt)){log.info("请求头token为空,返回未登录信息!");
//注意,在controller层中有@RestController注解可以将返回的类型转化为json格式,此处并不是controller层并没有这个注解,所以要自己转换,在pom文件中引入一个fastJSON的依赖Result error=Result.error("NOT_LOGIN");//TODO 后面不能加!,要严格按照接口文档里写的来做,如果notlogin后面加了!就会导致前端呈现出不一样的反应。String notLogin= JSONObject.toJSONString(error);//这样返回一个json格式的字符串resp.getWriter().write(notLogin);//然后通过resp响应给浏览器return false;}//5.解析token,如果解析失败,返回错误结果(未登录)try {JwtUtils.parseJWT(jwt);} catch (Exception e) {//解析失败e.printStackTrace();log.info("解析失败,返回未登陆的错误信息!");Result error=Result.error("NOT_LOGIN");String notLogin=JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return false;}//6.放行log.info("令牌合法,放行!");return true;}@Override//目标资源方法执行后执行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}@Override//视图渲染完毕后运行,最后运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterHandle...");}
}
//TODO 注册拦截器,将定义好的拦截器添加进去。
@Configuration//表明是一个配置类
public class WebConfig implements WebMvcConfigurer {@AutowiredLoginCheckInteceptor loginCheckInteceptor;public void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(loginCheckInteceptor).addPathPatterns("/**").excludePathPatterns("/login");//此处要注册一个拦截器并且表明拦截的是什么请求,注册的就是刚刚在Logincheckinteceptor中定义好的拦截器,所以前面要进行依赖注入//注意此处想要拦截所有请求是/**,过滤器中的是/*,用excludePathPatterns取消拦截指定请求,也就是说直接放行。}}

 注意:如果过滤器和拦截器都存在的话,是这样的执行流程:

Filter过滤器是servlet里面的,拦截范围比较大,interceptor是spring里面的,只有进入spring环境才会进行拦截;在拦截器中,限制性preHandle,如果校验正确,会执行controller层中的方法,访问web资源,然后再执行postHandle和afterCompletion中的方法。执行流程如下图所示:

Filter与Interceptor的区别:

接口规范不同,过滤器实现Filter接口,Interceptor实现的是HandlerInterceptor接口

拦截范围不同:过滤器会拦截所有的资源,拦截器只会拦截spring环境中的资源。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Zookeeper集群搭建】安装zookeeper、zookeeper集群配置、zookeeper启动与关闭、zookeeper的shell命令操作

目录 一、安装Zookeeper 二、配置Zookeeper集群 三、Zookeeper服务的启动与关闭 四、Zookeeper的shell操作 前情提要:延续上篇【Hadoop和Hbase集群配置】继续配置Zookeeper,开启三台虚拟机Hadoop1、Hadoop2、Hadoop3,进入终端&#xff0c…

智能社区服务小程序+ssm

智能社区服务小程序 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了智能社区服务小程序的开发全过程。通过分析智能社区服务小程序管理的不足,创建了一个计算机管理智能社区服务小程序的方案。文…

【C++】vector模拟实现、迭代器失效问题(超详解)

vector会使用之后我们来模拟实现一下,通过对vector的模拟实现,我们来说一下迭代器失效问题。 1.准备工作 在头文件vector.h里声明和实现函数,然后在test.cpp里测试代码的正确性。 在vector.h中用命名空间分隔一下,因为c库里面也有…

前端学习八股资料CSS(一)

🤔🤔宝子们,好久不见啊!今日继续分享前端八股笔记,好多友友们觉得笔记对于自己学习复习或面试复习或平时加强知识非常有用,收到了大家的好评,谢谢大家的喜欢,我会坚持继续更新的&…

【进阶】Stable Diffusion 插件 Controlnet 安装使用教程(图像精准控制)

Stable Diffusion WebUI 的绘画插件 Controlnet 最近更新了 V1.1 版本,发布了 14 个优化模型,并新增了多个预处理器,让它的功能比之前更加好用了,最近几天又连续更新了 3 个新 Reference 预处理器,可以直接根据图像生产…

小程序源码-模版 100多套小程序(附源码)

一、搭建开发环境 搭建环境可以从这里开始: 微信小程序从零开始开发步骤(一)搭建开发环境 - 简书 二、程序示例 1、AppleMusic https://download.csdn.net/download/m0_54925305/89977187 2、仿B站首页 https://download.csdn.net/downlo…

【Python-AI篇】K近邻算法(KNN)

0. 前置----机器学习流程 获取数据集数据基本处理特征工程机器学习模型评估在线服务 1. KNN算法概念 如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中大多数属于某一个类别,则该样本也属于这一个类别 1.1 KNN算法流程总…

Deepin 系统中安装Rider和Uno Platform

1、在系统的中断命令行中输入如下命令,安装.NET 8环境。 wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.debsudo dpkg -i packages-microsoft-prod.debsudo apt-get updatesudo apt-get insta…

[OpenGL]使用OpenGL实现硬阴影效果

一、简介 本文介绍了如何使用OpenGL实现硬阴影效果,并在最后给出了全部的代码。本文基于[OpenGL]渲染Shadow Map,实现硬阴影的流程如下: 首先,以光源为视角,渲染场景的深度图,将light space中的深度图存储…

反序列化漏洞浅析

Apache InLong 是开源的高性能数据集成框架&#xff0c;支持数据接入、数据同步和数据订阅&#xff0c;同时支持批处理和流处理&#xff0c;方便业务构建基于流式的数据分析、建模和应用。浅析Apache InLong < 1.12.0 JDBC反序列化漏洞&#xff08;CVE-2024-26579&#xff0…

基于微信小程序的移动学习平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…

SQL中的内连接(inner join)、外连接(left|right join、full join)以及on关键字中涉及分区筛选、null解释

一、简介 本篇幅主要介绍了&#xff1a; SQL中内连接&#xff08;inner join&#xff09;、外连接&#xff08;left join、right join、full join&#xff09;的机制;连接关键字on上涉及表分区筛选的物理执行及引擎优化&#xff1b;null在表关联时的情况与执行&#xff1b; …

【Linux】软硬链接和动静态库

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

Orleans集群及Placement设置

服务端界面使用相同的clusterid和serviceid&#xff0c;相同ip地址&#xff0c;不同网关端口号和服务端口号&#xff0c;启动两个silo服务&#xff0c;并使用MySql数据库做Silo间信息同步&#xff0c;实现集群。 silo服务启动代码如下&#xff08;从nuget下载Microsoft.Orleans…

iphone怎么删除重复的照片的新策略

Phone用户常常面临存储空间不足的问题&#xff0c;其中一个主要原因是相册中的重复照片。这些重复项不仅占用了大量的存储空间&#xff0c;还会影响设备的整体性能。本文将向您展示iphone怎么删除重复的照片的方法&#xff0c;包括一些利用工具来自动化这个过程的创新方法。 识…

C++ 的第一个程序

目录 一 . C的第一个程序 二 . 命名空间 2.1 namespace的价值 2.1 namespace 的定义 7.3 命名空间的使用 三 . C输入&输出 四 . 缺省参数 五 . 函数重载 六 . 引用 6.1 引用的概念和定义 6.2 引用的特性 6.3 引用的使用 6.4 const 引用 6.5 指针和引用的关系&…

C#开发基础:WPF和WinForms关于句柄使用的区别

1、前言 在 Windows 应用程序开发中&#xff0c;WPF&#xff08;Windows Presentation Foundation&#xff09;和 WinForms&#xff08;Windows Forms&#xff09;是两种常见的用户界面&#xff08;UI&#xff09;框架。它们各自有不同的架构和处理方式&#xff0c;其中一个显…

WPS Office手机去广高级版

工具介绍功能特点 WPS Office是使用人数最多的移动办公软件&#xff0c;独有手机阅读模式&#xff0c;字体清晰翻页流畅&#xff1b;完美支持文字&#xff0c;表格&#xff0c;演示&#xff0c;PDF等51种文档格式&#xff1b;新版本具有海量精美模版及高级功能 安装环境 [名称…

【Three.js基础学习】21.Realistic rendering

前言 课程回顾 渲染器 1.色调映射 值意在将高动态范围](HDR)值转换为低动态范围(LDR) Three.is中的色调映射实际上会伪造将LDR转换为HDR的过程&#xff0c;即使颜色不是HDR&#xff0c; 结果会产生非常逼真的渲染效果 THREE .NoToneMapping (default) 无色调映射 THREE.Linear…

TeamTalk知识点梳理一(单聊)

文章目录 db_proxy_serverdb_proxy_server reactor响应处理流程连接池redis连接池MySQL连接池 单聊消息消息如何封装&#xff1f;如何保证对端完整解析一帧消息&#xff1f;协议格式&#xff1f;单聊消息流转流程消息序号&#xff08;msg_id &#xff09;为什么使用redis生成&a…