00:00
好,我们现在来说一下spring boot在底层使用spring m VC来进行web处理的整个细节。首先第一个我们跟请求有关的请求参数处理,那么要在做所有外表开发之前,我们最先要做的事情就是请求映射,也要我们编写一个controller,在每一个方法上使用request mapping来声明我们这个方法能处理什么请求,把这个声明过程呢,我们称为请求映射,那请求映射呢,大家最习惯使用的就是request mapping注解来点进来request mapping注解里边,那我们这一块呢,有Y6 Y6呢和pass都是一样,他们呢代表我们当前请求能处理哪个路径,包括呢,这还有一个能处理请求的请求方式,这一块呢,就牵扯到我们请求处理里边的第二个叫rest风格,那我们说后来开发呢,我们都习惯于使用rest风格,因为我们以前,比如我们要对用户来进行增删改查操作。我们可因可能定义的URL路径是这样,Get user代表获取用户。
01:01
Date叫删除,Edit user叫修改,Save user叫保存等等一大堆,这样呢,感觉我们这样写到最后,我们整个项目一大期间,我们整个路径起名都感觉很麻烦,然后呢,那我们现在希望的就是我们所有对用户这个资源的操作,我们都叫杠U子,而怎么代表对用户的增删改查呢?我们风格大概就是说使用HTV请求方式的动词来表示对资源的操作,因为HTV请求它不仅有get方式的请求,还有put方式,Post方式,Delete方式等等等等一大堆,所以我们希望呢,能利用这些请求方式来区分我们对资源的操作,那我们现在呢,就应该是路径无论是增删改查都叫杠user,然后呢,如果你发get方式的HTP请求,那就是获取用户,Delete方式就是删除,Put方式就是修改,Post方式就是保存,这都是我们约定的规则。那我们以前使用MVC要来。
02:01
完成这个事情,那我们的核心是要给我们整个spring mvc中配置一个叫hidden htv me的filter,有了它才行,为什么要配它,我们来简单测试一下,好,我先把这几个测试代码我拿过来,我们就来放到hello controlrler里边,这是我们非常简单的,我写了四个方法,Get user给我们返回,Get张三,Save user,呃,那就是post张三,Put put张三,Delete delete张三,然后呢,请求路径都叫杠user,但是我是以什么方式我来区分,我到底是查询张三还是什么张三请求,我就是以后边method的方式,请求方式get post put delete,但这种写法呢,我问题就是我们的这个页面,我们页面的这个表单,Muscle的这一项我们来看一下,如果我们要写的话,Method的这一项我们就算写提示出来,它呢只能有get和POST2种方式,而我们的这个delete和put请求发不出来,那。
03:01
我们来尝试一下能不能发出其他方式的请求,比如我这有一个rest的delete提交,我看一下表单能不能发送delete请求,包括呢,我们能不能发送put请求,我们的put提交,我来启动一下我们的项目,来做一个测试。这是我们后来开发要经常使用的rest风格,我们先来给他测试通好们来访问到我们当前项目local host啊首页就行,然后呢,如果我是发送get提交,那就是get张三没问题,我发送post提交post张三也没问题,然后呢,如果发送delete,大家会发现put他们都变成了get张三,原因就是你写的这两个muscle。并不支持,也就是说它都会当成默认是get方式来到了我们这个请求处理,同样大家都是处理user请求,我能处理get,所以呢,后两个就来到了这,那我怎么能让它能处理put和delete呢?我们呢需要给我们spring mvc中配一个黑HD man filter,但是呢,按照我们这个boot来看一下web mvc auto configuration,那boot呢,整个对spring mvc的功能的配置在这,哎,我们看到它已经配了一个叫黑HD filter,也就是说我们默认就rest功能是能用的,那是不是这样,我们来做一个测试,如果你想要能用这个功能非常简单,我们把这个filter点过来,在这个filter里边呢,人家规定在HV man的里边,你只需要给我们带一个隐藏的参数项,叫杠man就行,好,我们把这个点开,我们来到页面,你想要真正的提要delete请求了,表单呢?
04:50
还是post方式,那为什么是post方式,因为在filter的底层,在do filter写的时候,只有你的表单是post方式,然后呢,我才给你把你表单里边真正提交的request get permit,把你提交的这个请求参数,这个请求参数就是它,它呢就是它,比如你表单如果是post方式,我就拿到你post表单里边的这个杠man速的参数,杠man速的,但我们一般呢,把它隐藏起来的,然后呢,杠man速的最终作为你的这个真正的我们的这个请求方式,比如我们现在想delete提交,我就写一个delete,然后呢,这边也一样,我们在页面想要提交risk风格,那必须都是这么来做,给表单上提交一个杠mano的隐藏参数,然后呢,我们在隐藏参数上写上它的这个请求类型。
05:41
好,我们来测试一下,看我们这种方式能不能实现我们的delete put提交。那其实按照正常我们这个页面一改,大家CTRLF9就行,因为我们已经引入了DV tos,好,我们来刷新一下,我们来测试一下delete请求M,发现delete呢,它还变成post,包括boot它还变成post,可是明明spring mvc在我们这个底层已经开启这个功能了,Spring boot已经开启了,那么就来好好分析一下,它是给我们容器中放了一个hidden htv method filter,那条件是什么呢?Conditional Miss,容器中没有的时候才放,然后如果你配了就按你的,那我们没配那他就放,然后呢,接下来有一个叫conditional on property,也就是说它呢判断我们配置文件中会配一个属性叫spring mvc hidden muscle的filter,然后enable,相当于是是要不要开启我们这个rest风格的这个hidden muscle的这个啊功能如果呢,我们没配这个大家看。
06:41
Match of Miss是force的哦,那就对了,也就是说如果我们没配这个功能,它默认当做啊是功能是不开启的,所以我们还得在这儿自动自己的开启一下我们这个功能,那我们这个功能呢,整个开启项就在这儿,我们把它CTRLC复制过来,所以rest风格我们想要使用,我们必须手动,在spring boot中需要手动开启,手动开启为什么要手动开启,我们也给大家找到了spring boot在底层,在自动配置的时候,说你这个没配,默认当你没配,呃,是当force的,所以我们来开启这个功能叫hidden filter。
07:21
我们来在这儿来开启一下。Hidden method filter enable,哎,它是for,我们来给它开成true,开成true以后呢,我们来重新启动,我们来看我们的rest风格能不能使用。来稍等一下,好,现在呢,我们这个已经启动起来,如果我们是来做页面开发,我们来看一下刷新,好,我来rest风格,首先get没问题,Post没问题,然后呢,Delete,诶,Delete张三来到delete方法,Put张三来到put方法,没问题,那原理又是什么呢?那其实就是给我们容器中放了一个这个filter,如果我们想要看真正它是怎么处理的,我们可以给filter的do filter方法打一个断点,好,我以debug的方式。
08:06
来看一下我们的这个表单,Rest风格的整个原理,原理呢是这样。首先我们再从页面上。好,我们把这个呢,先放行,这个第一个我们的第一个请求,我们先放行,我们真正发rest风格,我们再来看原理。把这个原理呢,我们来写到这儿,既然分析到这儿了,我们就要分析它的整个原理,Rest和原理,当然这个呢,原理是基于我们这个表单使用risk方式原理,这是我们这个表单表单提交,表单提交要使用rest风格的时候,它的整个原理呢是这样,首先我们这个表单提交会带上带上什么呢?会带上我们的这个杠man速的参数,因为按照要求,我们在这个表单里边带了一个杠man速的等于真正的请求方式的这个参数,所以会带上杠man速等于比如我们这个put,然后呢,接下来第二个,因为我们配了filter filter呢,这是一个过滤器,所以呢,请求过来会被菲尔塔拦截,过来被咱们这个菲尔塔拦截。
09:22
被我们的这个黑灯htv me的filter,它这个加了一个order的,只是加了一个优先顺序,我们不用管被这个拦截,被这个拦截以后呢,接下来它处理请求,它处理请求我们来看它拦截是怎么个拦截办法,我们来到黑灯hpman的filter,我们给它do filter打了一个断点。来做一个测试,Delete请求我们点过来,好,来到我们的杜菲尔方法,然后呢,首先拿到我们的这个请求来,这是我们原生的请求,然后拿过来呢,变成request to use啊,这是我们原生的请求,把我们原生请求拿过来,然后呢,他判断我们原生的请求的请求方式是不是post,所以这就要求我们必须表单提交的时候,必须是post方式才能使用表单rest风格,这是第一步,第二步他在判断我们这个request get atribute attribute里边,它获取我们当前请求是不是有没有什么错误啊,如果没啥错误,我们再来继续,所以我们这个请求呢,一切正常,我们来到里边方法,然后呢,接下来它request get this来request get permit,这个东西呢,是大家最常见的方法,在原生的request里边,它能获取我们请求参数,获取哪个请求参数呢?是我们这个叫this.man power man power呢,叫deault man power,也就是我们这个杠man的请求参数。
10:43
所以呢,他一进来判断我们这个请求是否正常啊,没有出错,然后呢,并且是咱们这个post方式,如果是然后呢,进来进来了以后呢,我们接下来要做的就是获取到杠men的参数的值。
11:02
获取到杠method速的的值,杠men的值,好,我们现在呢,确实拿到了杠man速的值,我们来到这一块断点,我们来让它获取杠门速的值,好杠门速度的这个值呢叫delete,这是我们表单里边带过来的这个delete,因为它获取的是请求参数,然后呢是delete以后呢,他判断你的这个值has length,相当于你有没有值,不是空的,不是空的以后呢,他把你这个delete管你大小写,他呢都以经的历史的这个区域信息给你转成大写。我们来看这个method呢,最终变成了大写,所以呢,也就是要求我们这个表单这块呢,大写的delete,小写的delete都行,来重新debug测试一下,看小写的delete可不可以。因为我们看到它会自动转为大大写的好,我们再来重新刷新。
12:00
走,然后呢,我们来到我们的这个请求,这是原生的请求,拿到我们的这个请求参数的啊,这个杠杆速的它是delete。啊,因为我们这个页面呢,应该是小写delete好,我们现在呢,把它重新放行一下,我们把这个页面呢重新编译一下。来到首页好刷新刷新刷新刷新,保证呢,我们这个delete方式,我们来查看源代码,我们现在呢写的是小写delete。我们要把这个放行。来看我们的源代码,原代码这一块呢,已经是小写delete没问题,来小写delete提交,提交进来以后呢,我们获取到的这个值,它呢是一个小写的delete没问题,只要我们有值,然后呢,它就会给我们to upper case来进行转化,最终转成大写的delete,转成大写的delete以后呢,接下来怎么办?它判断他们允许的请求方式里边包不包含你的delete方式,然后允许的请求方式我们来点进来,点进来以后呢,大家会看到是这么一个几何,所以呢,说明人家呢允许你给我发put delete和punch这几个请求,但除了我们HTV的get post外,它还额外兼容。
13:14
哎,我们看到了兼容以下请求,兼容以下请求哪些请求呢?就是这个啊,我们的put方式的,这是我们来用来做修改的,对吧,还有我们的delete方式,还有punch对判NCH方式啊,也就是说呢,支持我们这几个请求,那我们现在呢,是得delete请求在他的这个范围内,那就没问题,没问题以后呢,大家看怎么办了,接下来呢,关键核心在这整了一个HT muscle的request wrapper搞了一个rapper,然后呢,Vaper变成了request土柚子,原来request土柚子呢是原生request,然后接下来我们把这个vaper点进来,这个vaper呢,我们再来点进来。
14:02
它呢,继承于这个per,这个per呢,它还是呃实现了htp request,所以呢,它还是原生的request请求,只不过不同的是我们的这个waper里边,他接收一个man速的传参。也就是说我们来看啊,把我们现在新的请求方式传了进来,然后呢,Vaper把新的请求方式一保存,保存到它的这个参数里边,然后重写了http request get的方法,所以这一块呢,使用了一个包装模式,这是原生request,原生request我们都知道它是post方式,然后呢,我们现在有一个包装模式的这个waor。包装模式的咱们这个request vaper request和vaper里边呢,Vaper它呢重写了,因为我们看到这个vaper呢,它也是实现了原生request接口,我们这个vaper大家看继承于它,而它呢又是实现了原生的request的接口,所以呢它是原生的request,然后呢,只不过它在里边重写了get method的方法,而method返回的是我们传进来的值,所以呢它重写了get muscle的方法,Get muscle的方法,然后呢,返回的是返回的是传入的值,而我们传入的这个值呢,又是从请求参数中获取的杠man速的值,所以呢,相当于把原生的REQUEST1包装,一包装以后呢,接下来把这个东西。
15:40
Do,菲奥特,哎,我们整个知道菲呢一放行能放行的是vaper,所以呢,把下边我们过滤器量,过滤器量放行的时候,放行的时候,然后呢,用vaper作为request对象放行了。
16:00
放行了,咱们这个挖per,所以呢,以后后来人我们这个菲只要一执行过,后来人现在来到我们的这个方法里边,那来到我们这个方法里边呢,它的这个request相当于就变成了被包装了的那个类,所以在那个类里边,哎,我们一放行呢,因为放行的是waper,所以呢以后的方法,以后的方法调用get method是调用,是咱们这个调用vaper的,是调用vaper里边的request vaper的,所以request vaper呢,它是封装的杠man速的值,所以呢,我们以后调用呢,就是杠man速的,说什么就是什么,所以spring mvc在这判断你要发delete请求,它呢会把原生的请求拿过来,它一判断它的请求方式是delete,那就进这个方法了,他怎么知道请求方式是delete呢?就正因为我们在这个方法处理之前得先过filter filter呢,把原生请。
17:00
请求的这个请get muscle重写了,变成了delete,然后呢,我们在这儿拿到请求再来get muscle的时候,我们已经变成delete跟它就匹配了,所以呢,这就是我们的risk风格在这的,但这这个rest呢,它只是来做表单的,但是我们如果是risk使用咱们一些客户端工具直接发,那就跟他没关系了,客户端工具。比如我们安卓给我们直接发请求,人家能直接发一个,呃,Delete或者put,或者哪怕我们使用postman模拟也行,我们来P斯曼,P斯曼我们来发请求就跟这个没有任何关系了啊,我们来把它放行,来看P斯曼发请求还过不过我们的这个啊filter啊,过filter它还要不要包装。比如说如果是客户端方式,我们倒可以不用管。所以呢,它这一它这一项它是选择性开启,我们来可以来看一下啊,如果我来客户端,我们使用曼来模拟发发送请求,来添加一个请求给我们这个local host。
18:13
给我们这个local host,我们的来随便写一个local host8080。8080下边的我们的user发请求,而我们客户端可以直接选是请求方式,我选put方式,我点一个send,好send呢大家来看,来到我们的杜福,然后呢,我们的这个请求方式还是post吗?我们可以来看啊。我们直接相当于从HTTP层我们就已经不是post了,诶UI6诶这就已经是put了,所以呢们就不会进入到转换流程,直接放行,所以呢只有说是表单,表单呢,因为它只能写get和post,那表单呢,我们加上这个以后就OK了,所以呢我们现在原声的方式没有任何问题,哎,不影响原生功能。
19:03
对吧,使用客户端工具,如咱们这个postman直接发送get方式就行了,Postman直接发送put delete等方式请求来,无需我们这个filter啊,无需filter。这就是原理,哎,我们无需这个filter,所以呢,我们也能理解到为啥人家spring boot这一项呢,是选择性开启,因为如果我们不做页面开发,我们后来我们的这个spring boot应用啊,我们最多是用来做微服务开发,给人家提供接口,别人给我们发请求,我们返回接S数据,所以可能呢,经常都不交互页面,前后端分离,页面是别人写的,所以呢,我们在这。这是选择性开启,开启开启页面表单,页面表单的咱们这rest功能,哎,这是我们说的这个原理来,另外我们额外的一点就是我们这个request mapping,你来写get,来写delete,感觉这样太麻烦了,在spring mvc里边派生了一些新的铸件,它呢就等同于你既然是get方式,就等同于get man,大家来看get mapping呢,点进来其实就是request mapping get版,所以呢,我们在这呢,只需要来写杠user就行了,然后呢,这一块呢,就等同于post门p post门P好,我们在这,哎杠user,然后呢,同样的那这个那就等同于我们的put门皮,所以呢,Rise风格的这些映射,我们在这儿呢,直接可以来写杠user,以及我们这。
20:51
这块呢,就等于我们的delete门屏杠user,好,这是我们的这几个,同时我们来重新启动来测试,保证我们换了注解,它的功能还必须是正常的。
21:12
好,我们来重新来测试它的这个功能走。来刷新刷新。我点get这个没问题,Get post就不测了,主要delete好没问题,那么这个功能呢,一切正常,最后呢,给大家一个扩展点,既然我们把原理都讲在这儿了,那我想问大家,我在这表单提交的时候呢,这个参数名叫杠杠man速的,我们能不能变成自定义的名字,比如叫杠M,好,这个扩展点呢留在这儿,我们可以下一节课来给大家解析我们如何来实现这个效果。
我来说两句