00:00
前面我们测试了在参数位传入server let API以及它的内部原理,我们也可以在参数位置传入复杂参数map model a redirect attributes等等等等,那么再来测一下它,那着重来测这几个map model redirect attributes,包括solid response。那这几个是干什么的呢?首先map跟model它两个是同样的作用,就是我们在参数位置如果编写map或者model,我们给它们两个里边放的数据会被默认放在请求域中,所以呢,Map model map还有我们的这个model里边的数据会被放在咱们这个request的请求育种,所以呢,就相当于你调用了你给map model里边放东西,就相当于你调用了request set ATT tribute。相当于是调用了这个方法,然后呢,Redirect attributes这个呢是重定向携带数据的,来我们再来做页面开发的时候再说重定向携带数据。
01:05
重定向携带数据,然后呢,我们so select response,这明显就是我们solid API里边的response响应来,我们可以一会也来测一下,我们拿到原生的response,我们能干什么?好,我来测试一下,这是我们的这个map model,我专专门来写一个方法,还是来到我们request controlrler,因为我们现在呢没页面,我呢就做一个简单的测试,Public string test。好,我们现在来get monkey给我们来发送一个请求,这个请求呢就叫p pars,咱们的这个请求,然后呢,这个请求里边啊,我们来测一下,可以传入一个map map呢,我写一个string object这个类型的,然后呢,我的名字就叫map,或者呢传入一个model,然后呢,这两个类型呢,是属于我们说你操作这两个,给这两个里边放东西都是给请求域中放的,包括同理我可以给大家测一个HP so request,我们来验证一下是不是这个逻辑,包括呢,我们顺便来测试一下http response。
02:19
Server late response好,我们把原生的request请求response那都能拿过来,而且呢,这些东西呢,我们都可以直接来用,它也能帮我们来确定好参数值,返回什么呢?我先来返回一个,比如我来forward吧,转发到success页好转发到success页面,然后呢,我来做一个什么,如果你发po请求,我呢,给map里边放一个put一个put一个什么呢?Put一个咱们这个,比如我这个put一个hello。它的值呢,就是WORD666好,我随便写一个,然后呢,我给这个model里边我也放一个,比如put。
03:04
Model呢,它不叫put,它叫and attribute,添加一个属性,比如我呢叫word,然后呢,它的直叫hello 666。好,我呢相当于操作了map和model,给里边保存了属性,甚至于呢,我给request预中我调用set attribute方法,我保存了一个呃,咱们这个message,呃,我们不叫,我们叫这个message吧,下边有这些message,然后呢,这个message我们就叫hello word,好,我们保存了一些东西,然后呢,我们再来测试一下response,我也可以给response里边放东西,比如我们放了什么呢?我简单的一个我来按cookie,我让response响应的时候呢,添加上一个cookie,我来new一个cookie。我们让浏览器呢,给我们来保存上一个cookie,这样呢最好不过,我把这个cookie呢,再放进去cookie的KV来设置好,这个cookie的K呢就叫C,然后呢值呢就叫V1。
04:05
包括呢,我们整个cookie呢,是你也可以来设置它的最大的这个生命周期,还有设置它的整个啊do作用域等等等等,那我现在呢,全部都用它默认的这个RO set doin,作用域呢,就是local host。咱们这个本机就能作用域的,好,那我现在呢,在这儿准备了一这么一个程序,我以debug的方式来放在这儿。这个呢,打个断点好。我重新以deb的方式,如果我发送请求,最终呢会转发到success,那success呢,我想要确定map model request里边放的东西是不是在请求域中能取出来,那为了方便呢,我就直接在下边用它的这个request原生的属性get attribute。我来获取一下,保证呢,我说的那个是正确的,无论我是给map model里边放东西,Get at tribute hello。
05:05
还有request get attribute。Attribute,我们还放过一个word。包括呢,我们request.get attribute,我们还放过一个这个叫message。好,那甚至于呢,我们在这呢,还添加了一个cookie,我们不设置作用域了,我们这个cookie呢,最终我们给浏览器响应内容的时候,我们就看浏览器有没有给我们保存这个cookie,然后这个请求一发呢,最终会转发到success请求,我success呢把这几个数据都取出来了,那取出来以后呢,我给这也放上一些东西,map.put hello值是hello,然后呢,map.put我们的这个word的值是word。然后呢,我们再来map.put message的值是message,那就来看我们放的这几个值。
06:04
能不能获取到,那我先呢,以咱们这个正常运行,我先不debug正常运行。我们来看model request这三个的关系,是不是我们的这样子?包括我们response,我们操作原生API,能不能给浏览器发一个cookie回去。好,我来测试一下,我来访问这个请求。来当前向PS f12,我们来打开浏览器啊,这个控制台进行监控回车,好,我们这个请求呢,它是404,我们来重新启动一下我们这个请求。好,最终要写啊,Forward转发到forward forward单词写错了。我们来看一下效果。好,我来刷新我们这个请求,现在呢是400 400的原因说missing request attribute message,比如呢,我们缺少了这个请求属性,缺少请求属性的原因是因为我们这个请求要转到这儿,然后request attribute这两个东西呢,我们没传,所以呢没有,所以我们在这儿可以设置一个这个一个呢叫required force,就是我们这个东西呢,它不是必须的请求预中不是必须一定要带这两个,我们主要呢要测试下边的,好把这两个调成false ctrl f9,我让这个项目呢重新启动一下。
07:37
我们还是来主要获取我们hello word和message这三个值。我来刷新,好,我们来看到我们没传的呢,就是没传word呢是HELLO666HELLO是word 666message是hello word没问题,所以呢,印证了我们一件事情,我们给这个map model还这些操作,就相当于给request域中放数据。
08:00
我们把这个呢放在这儿,然后呢,对于我们这个model或者map的操作,就等于给他们里边填东西,就等于给request,这三个都是都是可以给request的域中放数据,放数据然后呢,我们以后呢方便request.get attribute来进行获取,同样的你到页面可以使用E表达式之类的都可以取出来啊,这是我们放数据,那原理又是什么样呢?我们可以来测试一下。我们的这个放数据呢,主要我来把这个断电打到这儿来,给大家看上这么一个现象就行了。我来debug,走起来。那它深入的原理呢,我们下一节课走到这,我们先来了解上一个现象,好,我debug走到这儿,我们现在来访问我们这个请求,包括我们来看S,我们之前这个cookie有没有起作用,Response,我们的整个响应,响应里边大家注意,我们给浏览器有一个命令叫set cookie ce1等于V1,所以呢,浏览器未来一定会给我们保存一个cookie ce1 V1,所以我们这个cookie的设置也是生效的,没问题,我对solid原生API的操作在这都没问题,然后呢,我们来重新发这个请求,我们来看一下原理,好,请求一发过来,我们在这儿执行,我放行,放行呢,在这来执行,我们这个目标方法来执行,然后解析我们这个参数,我们来放行,我们它来判断我们哪个参数,这个解析器能支持我来step into,进来进来来看一下,我先来放行第一个request p这个肯定不行,因为我们现在当前的这个参数,我们来看第一个参数呢,我们来写的这个东西呢,它是一第一个参数,第一个参数。
09:44
啊,PM0 PM0呢,它是一个map p1呢是一个model,还有request和咱们这个response,来看一下这个map model它是怎么解析的,哪个能支持呢?我们这个request不行,我再来放下一步,这个也不行,这个pass variable也不行,大家注意观察,这也不行,然后呢,这个matrix也不行,然后呢,So model attribute,这个model attribute也不行,我们之前说它呢,是来看你有没有标注这个注写的,所以我直接来放行response body也不行,然后呢,Request和part这个也不行。
10:20
然后接下来request header也不行。还有我们这个request header map肯定也不行,然后呢,Cookie value也不行,Expression value expression value呢,我们来放行它也不行,走起,然后呢,Sessiontribute也不行,Request attribute也不行,然后request也不行,然后呢,Response也不行,Htp nity也不行,Dire attribute也不行,然后接下来这有一个叫model method process。就是说呢,它判断你是不是一个呃,Model的,我们来step into进来看看,主要来看你的这个参数类型是不是model,而我们第一个参数呢,它是一个map,不是model,所以呢也不行,然后呢,接下来第二个叫map muscle的processor,所以来step into进来看它,看你这个参数类型是不是map,巧了,我们正好是,正好是以后呢,接下来他给我们来解析解析这个参数,好,参数解析器拿过来,参数解析器拿过来以后呢,我们来看一下它怎么解析,Step into进来,我们来让他拿到这个参数解析器,它肯定是从缓存中拿的,看他怎么解析走进来,进来以后呢,它会从这个里边,如果我们参数类型是一个map,它会在mav container mav container呢全称叫model and view container里边get model,也就说这个model and view container这个里边它呢有一个属性叫get model,来看一下get model,它是来获取什么的,Control f12 get model。
11:48
走get呢,它会给我们返回一个model map,这个model map呢就是default model,就是这个玩意叫Bing aware model map,所以呢,我们就看到了这么一件事儿,如果是map类型的参数。
12:03
Map类型的参数,我们就来写到这儿。Map类型的参数,然后呢会使用我们那个reserve,然后呢,最终给我们会返回,会返回咱们这个mav model and view u controller。Model and view Mo,人家这个叫什么玩意儿来着,嗯,我们来看一下啊,然后这个呢,叫mav container,它会返回mav container,也就是它里边的model get model,而这个model呢,它呢全称是一个Bing aware model map。点进来,点进来帮ing away model map点进来帮ing word model map,它既成于什么model map,它呢,既成于呃什么model map又实现model,然后呢,又是它呢又是map,所以相当于这个帮丁aware model map不仅是model。
13:05
它是model,也是map是model,因为我们来看到它的整个类声明是model也是map,所以呢,我们如果是map参数的类型,它会返回这里边的东西,那我们这个map呢,参数就确定好了,这里边的东西我们就让它返回,它来帮我们来get到model,然后呢,我们就直接让它返回,直接让他返回这个参数,好二哎,我们来看一下它获取到的这个model,这个呢叫Bing model map是5848这个对象,然后呢,接下来我们来确定第二个参数。来到第二个参数P,第二个参数呢?我们来看一下第二个参数我们的详细信息。第二个参数是什么?第二个参数呢,是第一个参数是map,第二个参数呢,我们现在变成了model,我们来看它怎么确定model同样在我们的这个reservevo,看支不支持step into进来便利所有的reservevo,那其中呢就会有支持的,我们挨个来判断,Request power不行,然后呢,Pass variable不行,大家注意这边啊,Matrix variable不行,Sole model不行,然后呢,接下来我们再来这,我们之前呢看过一个这个东西。
14:23
叫model muscle的processor也要说呢,我们第一个参数是map啊,它它呢是用下边的processor,我们来看一下啊,这个里边的东西呢,我们map呢,我们第一个用的是map的processor,我们第二个参数是model,我们用model,呃,Processor,所以呢,这个东西它是支持的step into进来看你的参数类型,如果是model,那就支持,一进来以后呢,我们来看这个参数解析器就找到了,来看它怎么解析参数的值,Step into拿到这个解析器怎么解析step into,我们发现它呢其实调用的是一模一样的方法,叫mvv container.get model,所以呢,无论是map类型还是model类型,底层呢都会调用,无论是map map还是model类型,我呢就直接写在一起,它呢,底层都是来调用了我们的这个方法,Get model,最终获取到获取到指导。
15:22
获取到值的,所以呢,我们来给大家看我们的这个model类型确定的值是什么。好,最终确定了完,我们来看我们的R,大家会看到我们的零号参数跟一号参数完全是一个对象,叫5845 5845,所以呢,我们这个参数位置传了一个map和model这两个东西,其实就是一个对象,5845,我们把这个5845这个对象大家打印在这儿。他们呢都叫Bing aware model map,所以呢,我们来看到我们的第一个参数位置,我们之前呢是写的是map,它呢是这个第二个参数位置,呃,这个字字怎么不好显示map,然后呢,第二个参数位置我们写的是model,但是无论是哪个都是相同的对象,所以呢,Map model的处理都是一样的。
16:15
那既然都是一样的,它为什么又能把数据放在我们的这个请求域中,我们可以来确定一下,好我们这个参数呢,确定,接下来我们来确定第三个参数,第三个参数就是我们原生的这个API,我们就不用管了,我们接下来就让它方法执行。我把所有的参数值,我们现在终于呃,让他把所有的,诶,我们这一块就直接放行了啊,放行放行放行放行。呃,我们应该来到我们的这个,它在这来判断,在这解析参数的值,解析完了以后呢,准备返回,我呢直接断点下到这儿,返回我们这个参数值,我们在这个F里边不下了,走,我们在这来解析,解析以后呢,返回返回好,接下来又是一个参数,我们让它解析,解析以后返回,然后呢再来。
17:08
好,我们现在呢,把所有的这个参数已经确定了四个参数,这两个map跟model都是同一个对象,然后呢,还有一个request对象,然后呢,还有一个response对象,然后接下来我们来看让它执行目标方法doing work这一块呢,那自然而然就是执行目标方法了,我要一放行,那就来到这里边,我一放行好来到我们这个目标方法,那目标方法执行完以后怎么办?这个目标方法呢,执行完以后in work for request,走我们这个in work for request,那自然就来到我们这个set response,这好,我们让目标方法执行完好来到我们这,来到这儿以后呢,我们最终目标方法的返回值是一个forward success对不对?那我们forward success以后呢,那接下来我们相当于就是要转发到啊一个地方,但是呢,转发之前我们把这个。MV container里边的这个东西,大家注意mvv container里边有一个这个model,这个model里边我们放了这两个值,因为大家会看到我们无论是呃什么东西。
18:14
无论是map还是model,都是这个model and view container里边的default model就是这个5845这个对象,所以5845这个对象呢,相当于我利用map跟model添加了这两个值,然后呢,这两个值又是怎么被放在请求域中的,我们可以来看一下,好,它在这set response status设置我们这个响应状态,这个响应状态呢,我们呃,这一块呢,暂时不用管,呃,相当于他告诉我们这个响应完成了,接下来他这一块,哎,我们也不用管。这有一个AV container,我们这个也不用管,来一看啊,接下来这有一个叫this,接下来handle return value,接下来开始处理返回结果了,用我们这个方法执行完呢,返回的是一个死证,处理返回结果的时候呢,把这个mav container也传进去了,我们就来看在处理返回结果的时候,这mav container有没有做什么操作,Step into进来。
19:11
好,它先获取返回的这个结果类型,不用管,再step into。我们来让它handle兜好处理我们这个返回值,处理返回值呢,他去来找到我们这个,呃,返回值的这个处理器,我们后来再说返回值,我们来看它怎么处理返回值,包括有没有操作什么处理返回值里边呢,很简单,在这如果你的返回值是一个字符串,从你把你返回的这个字符串拿到,然后呢给你保存到model and view container里边,当其实这个东西呢,一翻译就叫模型和视图的容器,然如果你返回到一个地方,这个地方的地址我们称为视图,而这个地方我们要携带的数据我们称为模型,无论是模型跟视图,全部都在模型和视图这个容器里边,最终呢,这有一个围诱对象,对吧,就是在这儿,所以呢,我们模型视图解析器,相当于给我们这个模型视图容器里边把要返回的视图地址我终于也放上了,还有我们的数据也在这儿,而这些数据呢,又怎么被放在请求域中,我们可以来。
20:16
往下边看一下,好,整个返回值处理完了以后,接下来这有一个get model and view,获取我们的这个model and view对象啊,我们来step into进去,然后呢,大家注意这有一个model,什么factory,我们这有一个模型工厂update model,所以接下来呢,所有的我们方法只要一执行完,所有的后续流程都是来处理这个mav contain的,就是我们的模型和视图容器,都来处理这个容器里边的数据,哎,大家一定注意啊,请求处理结束以后。确定每一个方法的值,确定完了以后,而且这一块呢,我们也是后来在在第四这说的556,然后呢,请求处理完了以后,第六步就是呢,我们方目标方法执行完成,目标方法执行完成。
21:11
将所有的数据目标方法执行完成,它会将所有的数据都放在model and view container,大家先跟他混个眼熟,我们翻译成叫模型和视图这个容器里边,这个里边呢,包含我们要去的,要去的页面地址,也就是我们说的5U,还包含还包含我们的这个model数据,而且model的这个数据呢,我们说就是你操作map跟model放在里边的这个数据,我们把这个呢重新截图给大家看。然后呢,他们对这些数据就要有一定的处理,但是这个怎么处理呢?我们来看它是怎么处理的。我们来看它如何进行来处理好它在这update model大家看啊,在这来要什么更新model什么东西,呃,我呢就过来来看一下啊,看它更新是干嘛什么step into进来,然后呢,相当于从model and view container里边拿到我们默认的这个model,就是5845,哎,这个hello word放了这个东西的,然后呢,接下来它在这呢,操作了一些东西,什么update一些东西,主要在这儿有一个update帮ing result啊更新我们最终的绑定结果,绑定结果呢就是在这大家看啊,拿到所有的这个model and view,我们里边的这个key啊key我们现在呢有两个k hello word这两个值,把这两个值呢,它每次遍历循环拿到我们拿到这个每一个的值,先拿到每一个model里边的值,如果呢,需要我们说明的这些什么,各种绑定,绑定我们说自定义对象的时候,后来说,然后呢,它就放到绑定里边,如果不需要我们就不用管啊。
22:59
Y6不等于空,而且呢,我们需要跟什么绑定好,我们现在呢,没有什么绑定策略,暂时不用管,然后呢,那最重要就来了,我们又是把这个model拿到,就是这个5845 5845,大家记住这个编号,然后呢,封装成model and,哎,相当于大家看把这个MV mav container里边的这个model数据,Model这个数据model这个数据5845,把这个5845呢传到进来,Model and view container又被封装成model and view model and view有什么用?它还判断,如果你的这个model是readdire attributes,那如果你是重定向携带数据怎么办呢?它呢就会把这些数据全部拿来,拿来以后呢,大家来看啊,葡萄奥现在又放到你的整个请求的上下文里边,而我们现在呢,不是重定向写带数据,那接下来我们来看啊。
23:55
我们这个方法执行完以后,Mav这个里边呢,Model里边是我们要用的数据,它是何时被放到请求域中的,我们再来往下走,让它呢,最终把这个mav给我们整个返回。
24:09
那我们相当于disppa的这一句话,我们真正使用适配器执行目标方法就全部结束了,结束了以后,那核心就在这儿了。核心我们来走下边啊,这有一个叫呃,Apply post handle,就是我们整个处理完了以后怎么办,如果我们来step into进来这一块呢,是执行拦截器的,我们后来会说拦截器原理,把这个拦截器呢放心,然后呢,主要在这叫process dispatch result,就是我们处理最终的这个结果,我们先跟他混一个眼熟,目标方法执行完成,接下来我们就要处理结果。处理派发结果,所谓的派发结果就是我们要去哪些页面,主要呢就是我们核心的这个方法,而在这个里边呢,它一定会把我们model里边的东西放在请求域中,我们就来找这处源码step图进来,好,然后呢,这跟错误处理有关的,我们不用管,然后大家注意这有一个MV,这个MV是什么呢?我们来看一下这个MVMV就是我们的这个model and里边带了我们这个。
25:16
带了我们这个hello word这两个值的,只不过呢,它重新封装了一遍,不叫5845了。5845的是model and container的,而把model and view container里边的值拿过来封装成我们的这个东西,但是我们这个东西它一定要在请求域中来看他是怎么处理的,那他在这render相当于要去哪个页面,他要开始渲染,怎么渲染的过来大家看啊,他在这呢,先拿到视图名,视图名我们是转发,然后呢,接下来他在这解析视图,解析视图我们来看他怎么解析,而且呢,解析视图前他把这个model拿出来。走,相当于把我们里边放的hello word这两个数据拿出来,至此我们还没有在请求于中来step into,大家看一下。
26:04
我再次带捕印into进来,然后来我们来看视图呢,又来到了视图解析器的流程,我们暂时不用管,现在呢,既然进来了,我们就来让他进来,我们来看一下他怎么解析,解析里边呢,核心关注一点,大家注意request Honda get我们的这个request attributes,拿到所有请求域中的这个属性,但是这个属性呢,暂时还跟我们model and view,呃,那个没啥关系,我们来看他把那个东西呢,在哪一步封装它获取到我们这个所有的这个视图。啊,我们把这个视图拿到啊,这个视图拿到,然后呢,解析得到视图名,视图名得到以后,接下来核心就来了,叫视图render,想我们要去的一个页面,页面呢要开始渲染,然后呢把页面的数据拿到。Step into,我再出来,再into进来,拿到以后呢,关键核心就在这儿了,这有一个叫create me的output model,创建一个叫合并的输出的模型,把我们这个model,这个model呢,相当于装了hello word这两个数据,然后我们请求方法里边只操作,相当于我们这个装了hello word,然后呢,把这两个东西传,把这个传进来,把request response也传了进来,Step into,大家看一下啊,然后呢,接下来最核心的又来了,在这儿我们一直往下翻。
27:25
翻哪呢,翻到这儿大家来看啊,我们拿到的这个墨model,这个墨model里边呢,没什么东西,然后大家this static attributes这一块呢,也没啥东西,我们的这个东西呢,在这儿如果大家注意。如果model不等于空,我们这个model呢,就是我们放到这个hello word这两个数据,然后呢,接下来他把model里边的数据全部放到墨model里边,墨model呢只是一个link的哈mapmp,所以呢,相当于他把这个数据又转移放到哈mapmp里边,这两个转移到哈mapmp转移到这有什么用?大家注意,我们接下来进入这一步,得到我们这个哈希map,把我们这个哈希map拿过来,然后呢,接下来prepare response,准备响应,准备响应这一块没啥说的啊,我们主要来看下一步叫render,叫渲染我们合并输出的这个模型数据,因为我们刚才呢,把我们这个model里边的数据最终拿出来放到这个map里边了,好,Hello word,然后呢,把这个map大家看又传进来了,传进来以后呢,调用了这个方法。
28:32
关键核心就在这儿,他怎为什么又能把这个数据,我们map model里面的东西放到请求域中,那我们追踪到这儿step into来进来,首先呢,他拿到我们的这个请求对象,这个请求对象大家看获取到原生的s request,就是这获取到原生的s request,我再次代才能进这个方法,进这个方法以后大家注意有一个叫。Expose model and request attribute叫暴露model作为请求域的属性,所以呢,大家会看到internal resource5右在这个里边,这其实就是我们后来的视图解析流程了,大家现在先混个眼熟,不指望大家能把这个掌握清楚,这个呢,然后呢,接下来它里边有一个核心方法就在这儿。
29:26
我们把这个核心方法里边的这句话拿出来。拿出来,那就是它expose model,也就是说它呢,我们翻译过来叫把暴露模型作为请求域的属性,所呢关键关键话就在这儿了,暴露模型。作为请求与属性。就是我们的这个关键方法,这个关键方法里边传的这个参数,这个model呢,一直是我们追踪的这两个带hello word的这个东西,我在step input进来,大家会发现超简单,就是把这个model里边的东西进行遍历,遍利以后呢,每一个request settribute就这么简单,所以呢,为什么我们map model,我们传的这个map普model它呢,归根结底它们是一个东西,而且呢,这一个东西它最终呢被放在请求域中,我们整个源码就追踪到这儿了,所以呢,它的这个写法就在这儿,这就是。
30:33
哎,我们通过一个典型的例子,我们能看到他的整个的运行流程。啊,这是我们,它是把model里边的所有数据,Model中的所有数据。中的所有数据便利挨个放在请求域中,那这就是我们说的我们自定义参数类型啊,我们不是自定义我们的参数类型,可以写map和model,而这两个东西的数据会被放在请求域中,放在请求域中呢,是在渲染的那一步放的,也是最终我们这个结果一返回我们spring mvc决定跳转到哪跳转之前放的这个东西,所以呢,大家一定注意,这是我们的这一块原理。
我来说两句