ssm+web面试相关

#Ajax和Axios

Ajax 即"Asynchronous JavaScript And XML"(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,可以给服务器发送请求,并获取服务器响应的数据。无需重新加载整个网页的情况下,能够更新部分网页的技术

Ajax 应用程序的优势在于:

  • 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
  • Ajax 引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。

Axios 是一种异步请求,对原生的Ajax进行了封装,简化书写,快速开发,安装 npm install axios --save 即可使用,请求中包括 get,post,put, patch ,delete 等五种请求方式。

<script>
// 引入 axios
import Axios from 'axios' 
export default {
	methods: {
		testAxios() {
			const url = 'https://www.baidu.com/' 
            Axios.get(url).then(response => {
            if (response.data) {
                console.log(response.data)
				}
			}).catch(err => {
				alert('请求失败')
				})
			}
		}
	}
</script>

Maven

是一款管理和构建java项目的工具。

什么是坐标?

Maven 中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置。使用坐标来定义项目或引入项目中需要的依赖。

Maven 坐标主要组成

  • groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
  • artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
  • version:定义当前项目版本号

生命周期

Maven中有3套相互独立的生命周期:

  • clean:清理工作。
  • default:核心工作,如:编译、测试、打包、安装、部署等。
  • site:生成报告、发布站点等。

上述每套生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。在同一套生命周期中,当运行后面的阶段时,前面的阶段都会运行。

Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际工作。**在Maven的设计中,实际任务(如源代码编译)都交由插件来完成。**这么多生命周期阶段,其实我们常用的并不多,主要关注以下几个:

  • clean:移除上一次构建生成的文件(clean自己是一套,下面四个是一套生命周期)
  • compile:编译项目源代码
  • test:使用合适的单元测试框架运行测试(junit)
  • package:将编译后的文件打包,如:jar、war等
  • install:安装项目到本地仓库

在maven中,可以在父工程的pom文件中通过 来统一管理依赖版本。子工程引入依赖时,无需指定 版本号,父工程统一管理。变更依赖版本,只需在父工程中统一变更。

dependencyManagement 与 dependencies的区别是什么?

  • 是直接依赖,在父工程配置了依赖,子工程会直接继承下来。
  • 是统一管理依赖版本,不会直接依赖,还需要在子工程中引入所需依赖(无需指定版本)

Tomcat

Tomcat是Apache 的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。Tomcat 也被称为 Web容器、Servlet容器。Servlet程序需要依赖于 Tomcat才能运行。

Web服务器是一个软件程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。还能够部署web项目,对外提供网上信息浏览服务。

Spring

事务管理

事务 是一组操作的集合,它是一个不可分割的工作单位,这些操作 要么同时成功,要么同时失败。

Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring 是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过 binlog 或者 redo log 实现的。

spring 事务实现主要有两种方法

1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法

  • 开启事务(一组操作开始前,开启事务):start transaction / begin ;

    提交事务(这组操作全部成功后,提交事务):commit ;

    回滚事务(中间任何一个操作出现异常,回滚事务):rollback ;

2、声明式,利用注解 Transactional 或者 aop 配置

@Transactional位置放在业务(service)层的方法上、类上、接口上。能够将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务。

IOC

控制反转,Inversion Of Control,简称IOC。

对象的创建控制权由程序自身转移到外部(IOC容器),并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。最直观的表达就是,IOC 让对象的创建不用去 new 了,可以由 spring 根据我们提供的配置文件自动生产,我们需要对象的时候,直接从 Spring 容器中获取即可。这种思想称为控制反转。

依赖注入: Dependency Injection,简称DI。和控制反转是同一个概念的不同角度的描述,即程序在运行时依赖 IOC 容器来动态注入对象依赖的资源。

Spring 的 IOC 有三种注入方式 :构造器注入, setter 方法注入, 根据注解注入。

  • @Autowired注解,默认是按照类型进行,因此不能存在多个相同类型的bean
  • 通过以下几种方案来解决:@Primary@Qualifier@Resource
    • @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解。@Autowired 默认是按照类型注入,而@Resource默认是按照名称注入。

Bean对象:IOC容器中创建、管理的对象,称之为bean。

  • 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写
  • 使用四个注解(@Component、@Controller,@Service,@Repository)都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
  • 前面声明bean的四大注解,要想生效,还需要被组件扫描注解 扫描。@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解 @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。

AOP

Aspect Oriented Programming(面向切面编程、面向方面编程),其实就是面向特定方法编程。用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect)。

作用:在程序运行期间在不修改源代码的基础上对已有方法进行增强(无侵入性: 解耦)

实现:动态代理是面向切面编程最主流的实现

SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。

Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理:

(1) JDK 动态代理只提供接口代理,不支持类代理,核心 InvocationHandler 接口和Proxy 类,InvocationHandler 通过 invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起,Proxy 利用 InvocationHandler 动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

(2) 如果代理类没有实现 InvocationHandler 接口,那么 Spring AOP 会选择使用CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现 AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法使用 CGLIB 做动态代理的。

核心概念

  • 连接点:JoinPoint,可以被AOP控制的方法(封装了连接点方法在执行时的相关信息)。例如:入门程序当中所有的业务方法都是可以被aop控制的方法。
  • 通知:Advice,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)
  • 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用。常会通过一个切入点表达式来描述切入点
  • 切面:Aspect,描述通知与切入点的对应关系(即通知+切入点)。通过切面就能够描述当前aop程序需要针对于哪个原始方法,在什么时候执行什么样的操作。切面所在的类,我们一般称为切面类(被@Aspect注解标识的类)
  • 目标对象:Target,通知所应用的对象。

通知类型

  • @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行
    • @Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行,其他通知不需要考虑目标方法执行
    • @Around环绕通知方法的返回值,必须指定为Object,来接收原始方法的返回值。
  • @Before:前置通知,此注解标注的通知方法在目标方法前被执行
  • @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
  • @AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
  • @AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行

通知顺序

不同切面类中,默认按照切面类的类名字母排序:

  • 目标方法前的通知方法:字母排名靠前的先执行
  • 目标方法后的通知方法:字母排名靠前的后执行

用 @Order(数字) 加在切面类上来控制顺序:

  • 目标方法前的通知方法:数字小的先执行
  • 目标方法后的通知方法:数字小的后执行

切入点表达式

切入点表达式:

  • 描述切入点方法的一种表达式

  • 作用:主要用来决定项目中的哪些方法需要加入通知

  • 常见形式:

    1. execution(……):根据方法的签名来匹配

    在这里插入图片描述

    1. @annotation(……) :根据注解匹配(Log是自定义的注解全类名)

在这里插入图片描述

连接点

在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等。

  • 对于 @Around 通知,获取连接点信息只能使用 ProceedingJoinPoint
  • 对于其他四种通知,获取连接点信息只能使用 JoinPoint ,它是 ProceedingJoinPoint 的父类型

SpringMVC

SpringMVC 是一个基于 Java 的实现了 MVC 设计模式的请求驱动类型的轻量级 Web框架,通过把 Model,View,Controller 分离,将 web 层进行职责解耦,把复杂的 web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

主要组件

前端控制器 DispatcherServlet:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。

处理器映射器 HandlerMapping:根据请求的 URL 来查找 Handler

处理器适配器 HandlerAdapter:负责执行 Handler

处理器 Handler:处理业务逻辑的 Java 类

视图解析器 ViewResolver:进行视图的解析,根据视图逻辑名将 ModelAndView 解析成真正的视图(view)

视图 View:View 是一个接口, 它的实现类支持不同的视图类型,如 jsp,freemarker,pdf 等等

SpringMVC 的执行流程以及各个组件的作用

在这里插入图片描述

1.用户发送请求到前端控制器(DispatcherServlet)

2.前端控制器( DispatcherServlet )收到请求调用处理器映射器(HandlerMapping),去查找处理器(Handler)

3.处理器映射器(HandlerMapping)找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。

4.前端控制器(DispatcherServlet)调用处理器映射器(HandlerMapping)

5.处理器适配器(HandlerAdapter)去调用自定义的处理器类(Controller,也叫后端控制器)。

6.自定义的处理器类(Controller,也叫后端控制器)将得到的参数进行处理并返回结果给处理器映射器(HandlerMapping)

7.处 理 器 适 配 器 ( HandlerAdapter ) 将 得 到 的 结 果 返 回 给 前 端 控 制 器(DispatcherServlet)

8.DispatcherServlet(前端控制器) 将ModelAndView传给视图解析器(ViewReslover)

9.视图解析器(ViewReslover)将得到的参数从逻辑视图转换为物理视图并返回给前端控制器(DispatcherServlet)

10.前端控制器(DispatcherServlet)调用物理视图进行渲染并返回

SpringMVC 支持的转发和重定向的写法

1)转发:

forward 方式:在返回值前面加"forward:“,比如forward:user.do?name=method4”

2)重定向:

redirect 方式:在返回值前面加 redirect:, 比如"redirect:http://www.baidu.com

SpringMVC 统一异常处理的思想和实现方式

使用 SpringMVC 之后,代码的调用者是 SpringMVC 框架,也就是说最终的异常会抛到框架中,然后由框架指定全局异常处理类进行统一处理

方式一: 创建一个自定义异常处理器(实现 HandlerExceptionResolver 接口),并实现里面的异常处理方法,然后将这个类交给 Spring 容器管理

方式二: 在类上加注解(@ControllerAdvice)表明这是一个全局异常处理类,在 方 法 上 加 注 解 (@ExceptionHandler), 在 ExceptionHandler 中 有 一 个value 属性,可以指定可以处理的异常类型

SpringMVC 中文件上传的使用步骤是什么样的? 前台三要素是什么?

文件上传步骤:

1.加入文件上传需要的 commons-fileupload 包

2.配置文件上传解析器,springmvc 的配置文件的文件上传解析器的 id 属性必须为multipartResolver

3.后端对应的接收文件的方法参数类型必须为 MultipartFile,参数名称必须与前端的 name 属性保持一致

文件上传前端三要素:

1.form 表单的提交方式必须为 post

2.enctype 属性需要修改为:multipart/form-data

3.必须有一个 type 属性为 file 的 input 标签,其中需要有一个 name 属性;如果需要上传多个文件需要添加 multiple 属性

Springboot

是 Spring 的子项目,主要简化 Spring 开发难度,去掉了繁重配置,提供各种启动器,可以让程序员很快上手,节省开发时间。

基于Springboot开发的web应用程序,内置了tomcat服务器,当启动类运行时,会自动启动内嵌的tomcat服务器。

请求

请求参数

简单参数

请求参数名与形参变量名相同,定义形参即可接收参数,会自动进行类型转换。如果方法形参名称与请求参数名称不匹配,可以使用 @RequestParam 完成映射。

@RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将报错。 如果该参数是可选的,可以将required属性设置为false。

实体参数

请求参数名与形参对象属性名相同,定义POJO接收即可(复杂的按照对象层次结构关系即可接收嵌套POJO属性参数)

数组集合参数

数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数

集合参数:请求参数名与形参集合名称相同且请求参数为多个,且用 @RequestParam 绑定参数关系

日期参数

使用 @DateTimeFormat 注解完成日期参数格式转换

JSON 参数

JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用 @RequestBody 标识

路径参数

通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用 @PathVariable 获取路径参数

Bean管理

获取bean

默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了。

主动从IOC容器中获取到bean对象的3种常用方式:

  1. 根据name获取bean

    Object getBean(String name)
    
  2. 根据类型获取bean

    <T> T getBean(Class<T> requiredType)
    
  3. 根据name获取bean(带类型转换)

    <T> T getBean(String name, Class<T> requiredType)
    

bean作用域

在前面我们提到的IOC容器当中,默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢?需要设置bean的作用域。

在Spring中支持五种作用域,后三种在web环境才生效:

作用域说明
singleton容器内同名称的bean只有一个实例(单例)(默认)
prototype每次使用该bean时会创建新的实例(非单例)
request每个请求范围内会创建新的实例(web环境中,了解)
session每个会话范围内会创建新的实例(web环境中,了解)
application每个应用范围内会创建新的实例(web环境中,了解)

可以借助Spring中的@Scope注解来在bean上进行配置

第三方bean

之前我们所配置的bean,像controller、service,dao三层体系下编写的类,这些类都是我们在项目当中自己定义的类(自定义类)。当我们要声明这些bean,也非常简单,我们只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个bean对象了。
但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,第三方提供的类是只读的。无法在第三方类上添加@Component注解或衍生注解,是我们引入的第三方依赖当中提供的。后续用@AutoWired注入即可使用第三方类。

解决方案1:在启动类上添加@Bean标识的方法

@SpringBootApplication
public class SpringbootWebConfig2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class, args);
    }
    //声明第三方bean
    @Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
    public SAXReader saxReader(){
        return new SAXReader();
    }
}

说明:以上在启动类中声明第三方Bean的作法,不建议使用(项目中要保证启动类的纯粹性)

解决方案2:在配置类中定义@Bean标识的方法

  • 如果需要定义第三方Bean时, 使用@Configuration单独定义一个配置类,并在类里面用@Bean定义第三方类
@Configuration //配置类  (在配置类当中对第三方bean进行集中的配置管理)
public class CommonConfig {
    //声明第三方bean
    @Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
          //通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名
    public SAXReader reader(DeptService deptService){
        System.out.println(deptService);
        return new SAXReader();
    }
}

在方法上加上一个@Bean注解,Spring 容器在启动的时候,它会自动的调用这个方法,并将方法的返回值声明为Spring容器当中的Bean对象。

注意事项 :

  • 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。

  • 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。

SpringBoot原理

起步依赖starter

如果我们使用了SpringBoot,就不需要像上面这么繁琐的引入依赖了(spring-webmvc依赖、Servlet基础依赖、jackson-databind依赖:JSON处理工具包、aop依赖、aspect依赖,项目中所引入的这些依赖,还需要保证版本匹配,否则就可能会出现版本冲突问题)。我们只需要引入一个依赖就可以了,那就是web开发的起步依赖:springboot-starter-web。起步依赖使用starter 启动器

为什么我们只需要引入一个web开发的起步依赖,web开发所需要的所有的依赖都有了呢?

  • 因为Maven的依赖传递。
  • 在SpringBoot给我们提供的这些起步依赖当中,已提供了当前程序开发所需要的所有的常见依赖(官网地址:https://docs.spring.io/spring-boot/docs/2.7.7/reference/htmlsingle/#using.build-systems.starters)。

  • 比如:springboot-starter-web,这是web开发的起步依赖,在web开发的起步依赖当中,就集成了web开发中常见的依赖:json、web、webmvc、tomcat等。我们只需要引入这一个起步依赖,其他的依赖都会自动的通过Maven的依赖传递进来。

结论:起步依赖的原理就是Maven的依赖传递。

自动装配

当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

自动配置的核心就在@SpringBootApplication注解上,SpringBootApplication这个注解底层包含了3个注解,分别是:

  • @SpringBootConfiguration

    • 使用了@Configuration,表明SpringBoot启动类就是一个配置类。@Indexed注解,是用来加速应用启动的(不用关心)。
  • @ComponentScan

    • 是用来进行组件扫描的,扫描启动类所在的包及其子包。
  • @EnableAutoConfiguration

@EnableAutoConfiguration这个注解才是自动配置的核心。

  • 以@EnableXxxx(不止是@EnableAutoConfiguration,其他第三方依赖也提供@EnableXxxx,用于自行加到启动类上,装配bean到IOC)开头的注解的底层,封装了一个@ import 注解,它里面指定了一个类,是 ImportSelector 接口的实现类。在实现类当中,我们需要去实现 ImportSelector 接口当中的一个方法 selectImports 这个方法。将配置文件中定义的配置类做为selectImports()方法的返回值返回。这个方法的返回值代表的就是我需要将哪些类交给 spring 的 IOC容器进行管理。
  • 此时selectImports()方法会去读取两份配置文件,一份儿是 spring.factories,另外一份儿是 autoConfiguration.imports。而在 autoConfiguration.imports 这份文件当中,它就会去配置大量的自动配置类(类名XxxxAutoConfiguration,配置类上添加了注解@AutoConfiguration,这个注解用于自动装配,底层就是@Configuration)。
  • 而前面我们也提到过这些所有的自动配置类当中,所有的 bean都会加载到 spring 的 IOC 容器当中吗?其实并不会,因为这些配置类当中,在声明 bean 的时候,通常会加上这么一类@Conditional 开头的注解(和@Bean并列使用)。这个注解就是进行条件装配。所以SpringBoot非常的智能,它会根据 @Conditional 注解来进行条件装配。只有条件成立,它才会声明这个bean,才会将这个 bean 交给 IOC 容器管理。

在Spring框架的生态中,对web程序开发提供了很好的支持,如:全局异常处理器、拦截器这些都是Spring框架中web开发模块所提供的功能,而Spring框架的web开发模块,我们也称为:SpringMVC

在这里插入图片描述

SpringMVC不是一个单独的框架,它是Spring框架的一部分,是Spring框架中的web开发模块,是用来简化原始的Servlet程序开发的。

外界俗称的SSM,就是由:SpringMVC、Spring Framework、Mybatis三块组成。

基于传统的SSM框架进行整合开发项目会比较繁琐,而且效率也比较低,所以在现在的企业项目开发当中,基本上都是直接基于SpringBoot整合SSM进行项目开发的。

到此我们web后端开发的内容就已经全部讲解结束了。

常用注解

1.@Component(任何层) @Controller @Service @Repository(dao): 用于实例化对象

2.@Scope : 设置 Spring 对象的作用域

3.@PostConstruct @PreDestroy : 用于设置 Spring 创建对象在对象创建之后和销毁之前要执行的方法

4.@Value: 简单属性的依赖注入

5.@Autowired: 对象属性的依赖注入

6.@Qualifier: 要和@Autowired 联合使用,代表在按照类型匹配的基础上,再按照名称匹配。

7.@Resource 按照属性名称依赖注入

8.@ComponentScan: 组件扫描

9.@Bean: 表在方法上,用于将方法的返回值对象放入容器

10.@PropertySource: 用于引入其它的 properties 配置文件

11.@Import: 在一个配置类中导入其它配置类的内容

12.@Configuration: 被此注解标注的类,会被 Spring 认为是配置类。Spring 在启动的时候会自动扫描并加载所有配置类,然后将配置类中 bean 放入容器

13.@Transactional 此注解可以标在类上,也可以表在方法上,表示当前类中的方法具有事务管理功能。

1.@RequestMapping(GET、POST、DELETE):用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。

2.@RequestBody:注解实现接收 http 请求的 json 数据,将 json 转换为 java 对象。

3.@ResponseBody:注解实现将 controller 方法返回对象转化为 json 对象响应给客户。

4.@PathVariable 用户从 url 路径上获取指定参数,标注在参数前 @PathVariabel(" 要获取的参数名")。

5.@RequestParam: 标注在方法参数之前,用于对传入的参数做一些限制,支持三个属性:

​ - value:默认属性,用于指定前端传入的参数名称

​ - required:用于指定此参数是否必传

​ - defaultValue:当参数为非必传参数且前端没有传入参数时,指定一个默认值

6.@ControllerAdvice 标注在一个类上,表示该类是一个全局异常处理的类。

7.@ExceptionHandler(Exception.class) 标注在异常处理类中的方法上,表示该方法可以处理的异常类型。

登录校验

登录校验,指的是我们在服务器端接收到浏览器发送过来的请求之后,首先我们要对请求进行校验。先要校验一下用户登录了没有,如果用户已经登录了,就直接执行对应的业务操作就可以了;如果用户没有登录,此时就不允许他执行相关的业务操作,直接给前端响应一个错误的结果,最终跳转到登录页面,要求他登录成功之后,再来访问对应的数据。

浏览器与服务器之间进行交互,基于HTTP协议,因为HTTP协议是无状态的,两次请求之间是独立的,所以在执行其他业务操作时是无法判断这个员工到底登陆了没有。

实现登录校验的实现思路可以分为两部分:

  1. 在员工登录成功后,需要将用户登录成功的信息存起来,记录用户已经登录成功的标记。使用会话技术。
  2. 在浏览器发起请求时,需要在服务端进行统一拦截,拦截后进行登录校验。使用统一拦截技术。

会话

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。

会话跟踪方案:

  1. Cookie(客户端会话跟踪技术)
    • 数据存储在客户端浏览器当中
  2. Session(服务端会话跟踪技术)
    • 数据存储在储在服务端
  3. 令牌技术

三者优劣

  • Cookie
    • 优点:HTTP协议中支持的技术
    • 缺点: 移动端APP无法使用Cookie。 不安全,用户可以自己禁用Cookie。 Cookie不能跨域
  • Session(底层基于 Cookie 实现。)
    • 优点:存储在服务端,安全
    • 缺点: 服务器集群环境下无法直接使用Session。Cookie的缺点他也都有
  • JWT
    • 优点: 支持PC端、移动端 。解决集群环境下的认证问题 。减轻服务器端存储压力。
    • 缺点:需要自己实现

JWT

全称:JSON Web Token

定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。

组成:

  • 第一部分:Header(头), 记录令牌类型、签名算法等。 例如:{“alg”:“HS256”,“type”:“JWT”}
  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{“id”:“1”,“username”:“Tom”}
  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。

JWT是如何将原始的JSON格式数据,转变为字符串的呢?

生成JWT令牌时,会对JSON格式的数据进行一次编码:进行base64编码

Base64:是一种基于64个可打印的字符来表示二进制数据的编码方式。所使用的64个字符分别是A到Z、a到z、 0- 9,一个加号,一个斜杠,加起来就是64个字符。还有一个等号,它是一个补位的符号

需要注意的是Base64是编码方式,而不是加密方式。

JWT校验时使用的签名秘钥,必须和生成JWT令牌时使用的秘钥是配套的。

如果JWT令牌解析校验时报错,则说明 JWT令牌被篡改 或 失效了,令牌非法。

统一拦截

Filter

概念:Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

过滤器执行流程是:请求 --> 放行前逻辑 --> 放行 --> 资源 --> 放行后逻辑

放行操作:filterChain.doFilter(servletRequest,servletResponse);

一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。顺序:注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序。

在这里插入图片描述

Interceptor

概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。

作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

执行流程如下

在这里插入图片描述

  • 当访问web应用时,过滤器会拦截。它会先执行放行前的逻辑,然后执行filterChain.doFilter放行操作。而由于我们当前是基于springboot开发的,所以放行之后是进入到了spring的环境当中,也就是要来访问我们所定义的controller当中的接口方法。

  • Tomcat并不识别所编写的Controller程序,但是它识别Servlet程序,所以在Spring的Web环境中提供了一个非常核心的Servlet:DispatcherServlet(前端控制器),所有请求都会先进行到DispatcherServlet,再将请求转给Controller。

  • 当我们定义了拦截器后,会在执行Controller的方法之前,请求被拦截器拦截住。执行preHandle()方法,这个方法执行完成后需要返回一个布尔类型的值,如果返回true,就表示放行本次操作,才会继续访问controller中的方法;如果返回false,则不会放行(controller中的方法也不会执行)。

  • 在controller当中的方法执行完毕之后,再回过来执行postHandle()这个方法以及afterCompletion() 方法,然后再返回给DispatcherServlet,最终再来执行过滤器当中放行后的这一部分逻辑的逻辑。执行完毕之后,最终给浏览器响应数据。

File与Interceptor区别

接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值