00:00
好,我们继续来debug,我来刷新一下,来到我们这个方法,我们重新进来,来到我们的dispat do dispatch方法,我们直接来放行,在这一块来真正处理我们这个目标方法,我们来放行,放法呢,放行了以后呢,它在这处理我们这个目标方法,执行完以后呢,会有一个返回值,好,我们来看一下我们这个目标方法,只要一执行完我们这目标方法的执行,执行完了以后呢,我们返回值是一个person对象,那么接下来看这个person对象最终如何被写为这个结算数据,那我们直接来放行,到我们可以来下一步,下一步我们都知道呢,返回值如果不为空的话,它呢在这会利用返回值处理器来进行处理,而返回值处理器的逻辑呢,我们之前已经进去看过了啊,我们再来step印度再进来,他呢先来找我们返回值处理器,而返回值处理器呢有很多,先找一个最合适的,哪个最合适呢?在众多返回值处理器中,只有一个返回值处理器叫,这个叫request。
01:00
A responsibility body muscle processor它呢,合适,呃,因为它可以支持,我们可以看一下啊,我们可以看一下,因为只有它可以支持,我们方法标注了response body注解的大家看,最终呢,返回的就是我们这个叫request response body,我们的这个method啊,Processor我们把这个copy value拿过来,所以呢,我们这个返回值解析器的这个原理就是它挨个找,看哪个返回值处理器能处理这个返回值,最终呢,找到了就是它。哎,我们把这个Y6值没有拿过来,好,我们一会拿过来吧,好,最终呢,找到了这个handle了,这个handle了呢,我们来step into直接进来这个handle了,就叫request response body CR home,好,来到这把它复制过来,最终呢,相当于在众多返回值处理器中,它可以处理,可以处理返回值标注,标注了咱们这个标了,标了咱们这个an response body注解的,所以呢,我们来到它里边,那来到它里边呢,我们来看它里边又是怎么工作的啊,我们来给它标上顺序,这是一二。
02:20
三那来到它里边,来到它里边呢,我们来看一下,在response body,我们来到这个processor以后,它既然能处理返回值,那前面呢,他在这儿做了一些准备啊,首先啊这有一些设置,比如把我们原生的request response,它呢全部包装封装到input message output这个message里边,哎,它在这呢,向当提取请求呢,它叫input message,响应呢,它叫output message我们可以能看到,哎,这个output呢是关于响应,然后呢,把我们的这个返回值相当于person对象返回值的类型,这是person类型,然后最终呢,以及请求响应都传给这个方法,这个方法呢来给我们来处理返回值,所以呢,最终我们返回值是由它来处理的,可以把这个方法呢记录到这,这个方法呢就是它里边的,那我们啊,核心就是来看我们的这个method的process。
03:21
这个处理器它是如何write with message converts,那翻译过来呢,就叫啊,使用我们这个消息转换器来进行写出操作,来使用消息转换器,使用消息转换器进行写出操作,所以呢,我们现在能看到的这个效果就是我们的这个processor如何处理response body注解标注的这些返回值,很简单,到最后呢,它是利用利用咱们这个叫利用message convert来进行处理,哎,我们看这个方法名呢,我们能听到它呢是利用message进行处理,那怎么利用message converts最终处理,然后呢,将数据写为阶S呢,写为咱们这个JS,写为咱们这个JS,那我们就可以看它里边的这个流程来看它是。
04:21
我们利用这个过程的好,我就直接step into进到这个message countl里边,进来以后呢,它判断我们这个值是不是字符串类型啊,我们不是字符串类型,我们是一个person对象,然后呢,把这个person对象拿来,把我们这个值的类型拿来,我们这个类型呢是一个person类型,然后把我们要转的目标类型拿来,然我们这个目标类型呢,也是一个person类型,然后接下来他判断is resource type,他呢先判断是不是资源类型啊,Step into什么叫资源类型?就是呢,它判断我们这个返回值类型,我们返回值类型呢是一个person,它判断我们这个返回值类型是不是input stream,相当于是这些流数据,而我们呢,这些不是流数据,如果是流的话呢,就调用它这里边对流数据的一些处理办法,比如呢,直接把我们这个流数据给他啊,响应到这个里边啊,那我们现在呢,不是流数据,那接下来就来到下边,下边呢,整个过程从二百零五行开始,大家会看到一个这个东西叫media type media type呢叫。
05:21
媒体类型,这个媒体类型呢,就牵扯到内容协商,所以内容协商,内容协商是什么,其实呢,我们简单来说啊,我们后来呢,还会说详详细原理,简单来说呢,我们先把这个断点给它重新启动。啊,我们给这样呢,打一个断点,内容协商是一个什么意思,就是我们浏览器要要什么样的内容,浏览器其实在发请求的时候就告诉我们这个服务器了,我们可以来监控这个请求,它呢相当于是来处理我们浏览器的这个细节,在浏览器我们来发请求的时候,好来请求发到这,我们来处理,处理来到我们这个目标方法来处理来到这个内容类型,这好。
06:04
我们来到这以后呢,我们来看这个请求有没有处理啊,在请求这块处理的时候呢,这其实有一个东西叫accept accept相当于就是我接受的什么东西,我能接受什么样的内容,所以这一块呢,相当于浏览器发请求的时候,告诉服务器,在他请求图里边告诉服务器我呢能接受HTML页面,能接受插麦,呃能接受插面呃也能接受图片,或者不行,我新杠星你给我给啥我都能接受,这个呢牵扯到我们后面的内容协商,给大家提前啊,先给大家啊,在这儿呢,拿出来比方说呢,内容协商的过程就是浏览器会告诉服务器我想要什么样的内容类型,浏览器会以默认默认,默认会以请求投的方式,请求投的方式告诉咱们这个服务器,告诉服务器它能。
07:04
接收什么样什么样的内容类型,那我们看到呢,我们默认的这个请求投里说他能接收HTMMR1大堆,但是大家注意这有一个新杠星,就是呢,我能接收所有东西,而这个Q等于多少,这叫权重,这个权重呢,大家看我们前边的这个HTML插面这些东西的权重是0.9,而我们的这个呃,Web页面,以及我们这个星杠星,我们这个图片啦,星杠星这些东西呢,它可能是呃0.8,所以呢这呢有咱们这个权重全0.9大于0.8,说明呢,我优先能接受页面啊,再不行呢,我接受你所有内容类型,所以呢,这相当于浏览器告诉那服务器我的处理能力,你给我给页面,给图片,给任何类型我都能处理,但是呢,服务器来到这该怎么处理,哎,中间的这个过程就是内容协商,内容协商的过程呢,我就直接给大家放行,你重新得bug来一次,好,我们来发请求,请求。
08:04
进来以后呢,浏览器上来就说我能接收HTML页面,再者不行我也能接受插慢,再不行我也能接受图片或者所有内内容类型,好,我们来看一下在这怎么办?好目标方法处理完了以后,Right with message converts,它会调用我们这个,呃呃,我们的这个processor会调用我们这个方案来进行处理,怎么处理呢?他在这有一个叫selected,嗯,Media type,那选中的内容类型,选中的内容媒体类型呢,没有,然后呢,他先拿到响应头,看响应头里边有没有内容类型,因为如果我们这个请求已经被前面处理了一半,可能已经有了响应的内容类型了,所以呢,他在这儿就会拿到前面处理了一半的响应的内容类型,如果已经存在了,大家看到啊,如果前面你已经处理了一半,有了这个内容类型了,我就直接用你的selected,相当于我我要用什么类型,我选中的媒体类型我就用你的,但我们这个请求啊,没有前置的。
09:04
处理过程,所以呢,前面也没有决定好内容类型,那接下来就来到这个环节来决定,首先拿到我们原生的request对象,然后呢,调用request对象的啊,调用这个方法得到一个叫acceptable types,我们能接收的内容类型,然后呢,最终在这呢,又又会得到一个produce,相当于我们最终能生成的内容类型,相当于浏览器告诉了服务器,哎,我能接收什么样的内容类型,看一下走这个我能接收什么样的内容类型呢?有七种,其实这七种呢是什么东西,这就是我截图的浏览器里边它列举的逗号,逗号列举的这些内容类型,所以呢,相当于他得到了浏览器给我们发请求的时候,浏览器具备什么接收能力,然后呢,再来得到我们这个,我们当前服务器能响应什么类型的这个数据,响应的这个内容类型,看我们这个服务器呢,能响应JS类型的数据,所以呢,我们在。
10:04
这一块叫get produce啊,我们的这个media type,我们的这个东西,这个东西呢,在这呢,就牵扯到内容协商原理了啊,相当于我们当前服务器会告诉。内容协商的整个过程就是服务器最终根据自己自身的能力,服务器最终根据自己,最终根据自己自身的能力,自身的能力,然后呢,呃,决定决定服务器服务器服务器能生产什么样的内容类型,能生产出什么样内容类型的数据,所以呢,接下来那浏览器说我能接收什么样的,服务器说我能生产什么样的,接下来在这呢,内容协商的一个主要过程就是大家看服务器,浏览器说我能接受这七种,而服务器说呢,我就能生产这四种,然后呢,服务器下来就跟浏览器开始匹配,我生产的这个东西,浏览器能不能接收,所以呢,一旦匹配成功啊,我能生产接森,浏览器也能接接收接森那。
11:17
一旦匹配成功,其实呢,这一块循环要多少次,这是七次,然后呢,这个是四次四七,因为这是一个嵌套FOR4728次,所以这28字for循环结束以后,会给我们的这个东西里边叫media type图右字里边放,我们到底能写出什么样的内容类型数据能看到在media type图use里边我们就决定了,哎,我们能给浏览器写jas接,浏览器能接收,为啥浏览器能接收,接S很简单,因为浏览器直接能接收新港新权重0.8,所以呢,我们现在能看到浏览器呢,能接收什么样的内容类型数据来权重0.8的啊,我们接S匹配型杠星都可以,所以呢,得到了我们这个内容类型以后,那最关键的一点就来了,根据我们的这个内容类型,然后要干什么呢?大家注意啊,最终得到我们的内容类型,我们相当于要把GS数据写出去,好写出去以后。
12:17
后呢,核心就来了,来到这就是什么呢?是来判断所有的message converts,大家注意这有一个所有的message converts,这又是一个for循环,大家会看到spring里边会用到非常多这种模式,我系统里边的所有的消息转换器,我看哪个消息转换器能支持把我们这个对象转成接次数据,所以呢,关键的核心就在这儿,一旦我们决定了用什么样的内容类型数据,然后接下来它服我们的这个spring l VC会挨个判断,会挨个便利所有呃,咱们这个容器底层的message convert,相当于我们称为的消息转换器,我终于见到了消息转换器的影子,它呢,其实是一个接口,给你所有底层的message convert,看谁能处理,看谁能处理他怎么知道谁。
13:17
处理非常简单,我们来看啊,Message count既然是一个接口,CTRL f12,它呢就规定了这些方法,其中呢有些是返回布尔不尔呢,我们看到有一个叫can read can write,翻译过来呢,我就是能不能写,能不能读,然后呢,它不仅有读写,大家注意这呢还会传一个叫媒体类型,相当于我的这个消息转换器,支不支持把我们比如person对象,然后呢以Jason字符串的方式读进来,支不支持把我们这个person对象以Jason字符串的方式写出去,所以呢,每一个message convert是具备相关的能力的,所以呢在这挨个病例看谁能处理,把这个拿过来来就是这,所以呢,这是我们这个message converter,我们把message converter呢放到这啊,Message converter简单描述就是一句话,什么叫message converter?
14:17
消息转换器翻译过来,它就是来看消息转换器的作用就是来看,来看我们是否支持,看是否支持将此此什么呢?此class类型,哎,老师就直接写它第一个将此class类型的咱们这个对象,然后呢,转为咱们这个media type类型的数据数据举一个例子,哎,举个咱们这个例子例子例子呢,就是我们支不支持将person对象转为杰数据,当然也可以逆向读,那就是如果你给我发请求,你带了一个杰森字符串,对吧?那就是我能不能把杰森转为person,而如果是写,那就是我要把我返回的这个person对象能不能写为杰森,所以呢,这是。
15:17
Message convert是一个可逆的过程,对象转接或者解转,对象接转为person,那就是要看你是请求还是响应,如果是响应,那我就是要写出去,如果是请求,我就是要转回来。哎,这其实就是这么一个简单的原理,好,我们这个message convert有了,那接下来他就在这挨个判断哪个message convert能干活,既然我们来看一下系统中有几个message convert啊,有挺多的,十几个呢,但是每一种message convert呢,它的能力不同,虽然message convert很多。我们可以把众多的message convert都列举在这来,我们这个message convert原理我们放到这儿啊呃,原理第一个message我们就叫message convert的接口convert规范,这是我们这个message convert规定的规范,然后呢,接下来第二个,而message convert呢,我们现在我们系统里边默认默认的message convert convert,而默认的这些message convert,它又能干什么,我们可以能看到。
16:35
它呢,接下来是一个for循环,给我们挨个判断哪个message convert能干这个活,所以呢,我们关键点就到了这个for循环,这个for循环呢,拿到第一个message convert water,第一个message convert water,我们来看一下叫什么啊,第一个message convert叫betterray,这样他判断message convert是不是这个类型的,如果不是给你强转过来啊,好,第一个message converter他拿来以后,他会判断看right能不能,哎,能不能支持我们这个写操作,它怎么判断呢?首先会调用message convert里边的support方法,判断支不支持我们这个类型的返回值,所以大家会看到第一个message convert只支持BYT类型的返回值,所以大家我们来提住啊,零只支持,只支持BYT类型的,所以第一个message convert不行,因为我们返回的是person,然后接下来看第二个,第二个呢叫string message convert,所以我们就直接放行吧。
17:35
啊,然后呢,接下来第二个,第二个呢,Can right,我再step into,然后呢接第二个呢是来到了,我们来看它的support进来,第二个叫string message convert,它呢只支持返回值类型为string的,所以我们会发现二是支持string来,我们就对应好这个啊序列啊接下来我们来看二号,索引为二的message索引为一的message convert就是第二个只支持string,索引为二的,大家会发现这两个呢,其实是一模一样,只不过他对象创多了,那好无所谓,那二呢肯定也是四准,我们不用说,然后呢,索引为三的。
18:14
啊,我们不妨进来都看一下啊,这是索引为二的,将来索引为三的这个message convert还叫string,它的这个判断方法呢,还是一样啊,只支持string类型的,我们就不用管了。好,索引为三的,我们来看这个叫resource HT message convert来看它只持什么样的,它呢支持返回值为resource,所以大家会看到三呢,只支持返回值为resource,接下来来到第四个,第四个message convert叫resource region,我们来看一下它能支持什么。所以我们会发现message convert虽然多,但不是所有人都能工作来我们在这判断,他判断呢,我们这个是不是参数类型,参数类型呢,相当于是不是这个玩意儿,哎,它判断返回值是不是这个,它呢支持这个返回值的,所以呢,每一种message convert它的功能效果都不一样。接下来我们来又来到这个message又叫source http来看啊,Source我们之前应该看过了,它呢支持,诶支持叫我们会看到这个呢是一个哈希set,它能支持很多,叫contains,它是来判断这个集合里边这个集合点进来,所以呢,它相当于来支持这几个。
19:29
这几个。我们的第五个source啊,S我们没看过,我们看的是resource,好,第五个它呢,能支持这么多啊,DOM source的,这相当于这这其实都是跟插mer相关的啊,DOM解析萨克斯解析的,大家能看到对吧,这是能支持DOM的,支持萨克斯的,包括支持STAX的,所以这一大堆,嗯,我们就把这个大家留在这就行了,这还有stream的。
20:05
好,还有我们的这个source,所以呢,每一种message convert相当于它呢,只能处理它指定类型的这个东西,有的同学说spring加为什么不写一个超厉害的message convert呢?那样的话,那一个message convert类里边可能要写的东西太多了,所以人家基于这种架构设计啊,加上我们的这些设计模式,我们就整个层次呢会非常清晰啊,那么现在来到我们这个message convert,它呢也不支持,那接下来来到下一个message convert,这个叫O,什么in coming,我们来step into进来。它呢向来只支持multi value map的,所以呢,第六个这种叫all in comp pass pass的这个它只支持Mo value map的,接下来第七个,第七个叫map扎son two h78都一样,我们来看第七个支持什么。
21:05
好,接下来来到第七个message convert,第七个叫mapping Jackson into来step进来来step into进来呢,诶,Suppose方法一不小心跳过了,但是大家注意这个suppose方法直接返回V处,所以呢,你会发现mapping扎son这个东西啊,它直接返回为出,也就说你不管是什么我都支持,这就解释了一个什么现象呢?那为什么我们相当于原理走到这一步。原理诶,我们之前总结的文字原理,哎,我们走到这一步,Message convert,其他人都不能用,只能用到这个mapping Jackson啊,To呢,因为他返回的是处,其他人还得有判断,其他人只支支持其他类型的,那八也一样,肯定是返回处,而九呢,那就是返回的是再是其他类型,叫Jackson b,我们来看一下啊,GA XB two,咱们这个message convert http message convert是不是叫这个collection,我们来看一下啊,是不是叫这个加加b root element啊,Root element message convert,它呢相当于支持什么类型,呃,它支持这个我们来看一下啊,Can read can write can write,它呢支持相当于你标了插相关注解的对吧,所以呢,一种呢是原生处理,一种是呢是标注理,标注解处理,所以呢,我们来看一下啊。
22:39
支持注解方式插麦,支持支持注解方式插门。插码处理的,所以呢,我们现在能看到只有第七个,而且我们现在也便利到第七个是满足要求的,那来到我们的这个mapping扎斯two HT message converter以后。
23:04
好,既然它能支持,他接下来判断看right,看right怎么判断呢?看type,我们相当于是person类型,Person类型呢,我们这个person类型的这个对象能不能转成我们指定的叫application Jason类型,Step to,进来进来呢,这就是Jackson to message convert能不能支持呢?他在这调用砍right进行判断,哎,Convert呢,其实他在这来判断啊,上边看你媒体类型是不是为空,即使为空它也能支持,或者呢,你不为空,它得到自己能支持的,而呢,每一个message convert都有自己能支持的媒体类型,哎,我们这个,比如我来step into step inTo Get a support大家会看到啊,我们的这个message支持什么呢?点进来,点进来它呢支持一个。叫collection来step into看看一下啊,它最终呢,支持的就是我们返回的那两个叫杰森。
24:05
比方说我们Jackson的这个message convert支持返回杰森数据,然后呢,接下来杰son数据,我看能不能适配我们想要的这个媒体类型,因为我们前面内容协商,然后我浏览器能接受什么,你说你服务器能干什么,然后这两个能匹配上,然后在这呢就进行匹配,然后呢,我能产生JS,你服务器呢,你浏览器也能接收JS,那巧了,那咱俩正好能做,能做以后呢,接下来它就在下边来进行处理,来看一下在下边处理,在下边处理呢,用这个object member,这相当于是Jackson Jackson底层的一个组件,这个object member呢,来帮我们来进行处理,大家注意看我们这个convert convert呢相当于终于这个if判断成功,判断成功呢,他拿到我们这个body,相当于我们需要响应的内容,这个内容是什么呢?来我们这个内容呢,其实就是一个person对象,把这个person对象呢,想要写出去,但是以接方式写出去,怎么写它呢,会加一些header,写之前加一些头。
25:06
我们不管,接下来用convert现当消息转换器的write方法,哎,大家还记得我们message convert接口没接口呢,就是can right,先判断能不能写,如果能写我就调用write方法把你写出去,所以呢,这个write方法我们可以四代平行图进来,进来呢我们就会发现好,他呢拿到我们这个响应头这一块响应头里边呢,什么东西都没有,默认是零个啊,这是一个response response响应头,然后他添加默认的响应图,因为我们要写杰数据出去,所以响应头里边会有一个叫contain ne type内容类型,内容类型呢叫application杰好,然后呢,再接下来我们就会发现整个过程叫right internal,对吧,想要把我们这个数据person对象,这个呢是person类型,最终呢写给response,写给响应,怎么样写出去呢?因为我们调用的是Jackson的这个message convert,所以呢,肯定这个Jackson它本来就是支持杰son的。
26:06
它肯定呢是以节省方式写出去,所以大家会看到底层呢,就进入到了扎克son来把一个对象转接省的流程,先拿到我们这个生成器,拿到生成器以后呢,拿到我们一些对象类型,好,然后大家注意拿到我们这个writer object writer,拿到这个writer以后呢,调用write方法啊,把我们这个对象呢以接省方式写出去,大家看在这write write以write以后呢,相当于write之前这还是一个对象,那write以后呢,把这个对象最终就会flash,相当于写出去,写给谁呢?写给我们的这个output message写给响应了,所以我们这个响应里边点开在它的响应题里边,点开响应题里边我们来看它的buffer里边,Buffer里边呢,肯定有一些流数据,这个bitt buffer,这bitt buffer里边呢,这有一个BAT数据,们来看一下BAT数据,我们让它以string方式展现,诶,我们看到这就是一个介所。
27:06
这呢,其实就是我们底层message convert,我们Jackson to的message convert能处理任何人,把任何人能转为杰森,所以呢,最终就是我们的这个message convert,他呢把我们这个对象转成杰森写到response里边去了,最终就是这个。最终呢,就是这个我们的哪个叫Jackson two mapping Jack two啊CN叫mapping Jackson to htp message contact,就是他他呢最终是帮我们来进行处理的,最终他然后呢,把对象对象转为基层,怎么转呢?就是利用底层的扎克son包底层的利用。利用底层的扎斯的object member转换的,所以呢,我们看到了整个的过程也非常简单,Spring mvc呢,先利用我们的返回值处理器,得到我们能处理response body这个注解的这个处理器,这个处理器里边呢,利用message convert便利循环所有的message converter看谁能处理,就是它能处理,然后呢得到它,得到它可以将对象,可以将对象写为介词,写为写为杰S,所以呢,那最终咱们这个呢,就会利用利用它,然后呢将对象,将对象转为杰森再写出去,所以整个过程呢,其实。
28:57
这就是一个message convert的原理,好,这就是我们说的返回值处理请求message convert的整个我们称为消息转换器的原理,这个消息转换器呢,我们知道底层呢,虽然很多啊,虽然很多默认有十几个,但是最终呢,我们会发现七号能支持将任意对象转为我们这个指定的,但如果我们返回的是别的东西,诶,比如我们返回了一个resource,对吧,我们返回值直接返回了一个资源,那这个资源呢,那肯定就被直接写出去了,就是各种不同的这个返回值处理器,那就能处理不同的这个方式,那返回值处理器里边呢,只要你标了response body,比如我们可以来举一个这个场景的例子,只要你标了response body,那它就会利用返回值处理器,利用request response body这个返回值。处理器为指处理器里边的我们的消息转换器消息转换。
29:57
器进行处理,所以呢,你其实可以非常方便的来做一件事情,就是public,比如我返回一个resource,我来返回一个资源,这个resource呢,它这一定是我们来看一下啊这个资源类型啊,Resources来看它支持哪个control n,我们有一个叫resource http message converter message converter它呢是支持这个类型的,这个类型呢相当于是一个input stream是我们这个spring framework IO这个类型的,所以呢,我们如果能返回一个这个类型的数据,它呢也能直接给我们整过去,这个类型呢,我们来看一下啊CTRLH它有没有实现类,这个实现类里边呢,会有一些比如htp resource,我们返回一些HTP资源,这个资源呢有压缩包的方式,还有文件的方式,所以大家给他可以在这实验,包括抽象的资源里边也有路径的方式,压缩包的方式,系统文件的方式。比如。
30:57
你可以呢,呃,返回一个系统文件的方式,大家自己可以在这尝试一个啊。
31:04
我们说到内容协商的时候呢,可以把它写完,大家可以在这儿返回一个资源的啊文件文件资源,然后呢,相当于啊废了,然后呢,这个文件资源呢,你最终返回出去,只要它是以responsibility body写出去的,首先大家一定要用responsibility body写出去,然后呢再来get map,比如我们就叫哈H啊111,然后呢,你只要返回这个资源,那相当于呢,它整个联动起来就是这个效果,因为你标了response body注解,所以呢就会调用这个返回值,处理器调用它,而他呢,最终又调用底层的message convert,而底层的message convert各种啊,各种人有各种不同的处理方式,又调用底层的message convert message convert,但是大家注意,那么接下来的这个message convert就不。
32:04
把它写成杰森了,而写成什么写成文件的方式,所以呢,大家在这可以来填充一下,哎,我们可以将文件文件以这样的方式返回,给大家留成一个作业吧,我们先不说以这样的方式返回,看是谁处理的,是谁处理的,大家来可以来底层追踪是哪个message convert处理的,它呢,又是怎么处理的?好,这是我们说的message convert原理。
我来说两句