00:00
前面呢,我们说了一下内容协商,在内容协商里边呢,我们总结一下它的完整流程应该是这样的,我们想要给客户端响应数据,我们呢,大的总结我们说能响应两种,第一种我们直接跳转一个页面给客户端响应,第二种我们响应各种各样的数据,而我们现在整个内容协商呢,讨论的是第二种,我们要做第二种响应数据,我们最开始的一句话就是我们给每一个请求处理方法标注了一个叫response body注解,相当于我们这个数据呢是直接响应出去,而不是跳转页面,那这样呢,我们数据直接响应出去,它原理呢,又是这样子的,哎,我们再来串一下,它原理呢,首先只要你标了responsibility body这个注解,代表呢,我们数据想要响应数据,然后呢,Spring mvc在底层就会调用一个叫request response body method的processor这个返回值处理器来处理我们这种返回值,然后呢,我们这个处理器呢,它又是底层通过调用各种method。
01:00
地址convert相当于我们这个消息类型的转换器,来进行我们数据类型的转换,而这些消息类型的转换器呢,每一种类这个message convert他们呢,其实都能操作各种各样的这个媒体类型数据,所以呢,我们系统底层所有的message convert合起来就相当于我底层能支持多少种媒体类型数据的读写,所以我们内容协商呢,最终就是通过确定我客户端想要什么样的类型的数据,和我底层所有的message convert,我们能写出什么样的数据来进行一个内容协商,最后协商到我们客户端能兼容,能给我们客户端写什么数据,你就写什么数据。而我们现在呢,又可能会有这么一个场景,我们要来自定义message,什么场景呢?举一个例子,还是我们的这个person方法,比如浏览器给我发请求,你直接在浏览器页面给我再发请求,我呢希望返回的是插数据,而如果是呢,你Ajax给我发请求,我。
02:00
我可希希望同样给我这个方法发请求,我希望呢返回接S数据,好,我们把我们的这个场景梳理一下,第一个如果是浏览器发请求,我们希望直接返回长吗?然后呢,第二个如果是aja请求来,我们用GS发的请求,我们来返回杰森,这样我们GS好操作。第三个如果是我们假设我们这个应用现在有一个a appmp,我们的这个客户端,如果我们这个硅谷APP来发请求,返回我们这个硅谷自定义协议数据,返回我们这个自定义协议数据,所以呢,我们想要完成这个事情,以前呢有三种办法,我们相当于要适配三种不同的客户端,我们有三种办法,怎么三种办法呢?第一种就是我们来直接写上三个方法,这三个方法请求路径都不一样,你浏览器呢,给呃一号路径发,我们的AJ给二号路径发,然后呢,APP给第三个路径发,但是有了内容显。
03:00
但我们就完全可以让一个请求能适配多种内容类型,所以呢,回顾起来,我们这个内容协商想完成这个事情非常简单,因为浏览器发请求,浏览器的请求头说我能接收application application插,所以呢,最终通过内容协商,我们中间呢会有convert能支持把我们这个数据转成插,所以呢,我们最终给它返回插麦。而如果是我们这AJS,我们呢,发请求,我们也规定我能接收,哦,不对,CAJS,而我们在其中呢,我们又会找到一些convert,如果呢是查麦,我们是找到查尔的这个convert,我们是扎克son,扎克son支持查尔的这个convert,而如果是我们杰森,我们找的是扎son支持杰森的这个convert convert,而如果是自定义类型数据,那你发请求的时候,你就告诉我,我要的是你把这你的这个数据转成application,比如我们自定义类型叫这样X。
04:00
硅谷所有的X代表我是扩展的协议啊,硅谷这是我们自定义协议,那我就应该找到一个叉叉叉convert water是不是能帮我来进行处理的,所以呢,现在我们想要完成我们这个自定义类型数据的写出,那我们的整个步骤就应该是这样子的,首先第一个我们就得添加一个自定义的message convert进系统底层,只有我们把我们的这个message convert添加到底层了以后,接下来我们系统底层,系统底层每次在内容协商的时候就会统计,就会统计出,统计出所有message convert能操作哪些类型数据,所有message convert能操作哪些类型,然后呢,等他统计出,哎,我们还有一个自定义的这个message呢,能操作and硅谷了,然后呢,进行客户端内容协商,客户端内容协商怎么写?
05:00
这样呢,就是客户端说我要硅谷类型的数据,而我服务器巧了,正好有一个convert能给你操作硅谷类型的数据,最终我们的convert就会起作用来进行操作,所以呢,我们现在就想要实现这个逻辑,那这个逻辑我们把convert怎么往系统里边添加,首先呢,系统底层会有一些默认的convert,默认的convert在哪?我们可以打开web mvc auto convertguation,我们来看一下在我们spring m VC的这个自动配置类里边,除了配spring mvc的一些其他功能添了一些filter外,大家看到我们这呢有继承了实现了一个mvc con啊,这也是一个配置类,它里边呢给我们额外的还配了一个叫哎conig message convert,相当它会给我们来配置message convert,那系统一加载的时候呢,系统底层的message c就配好了,怎么配好了,我们会看到它是将所有的convert从这获取到convert直接加进去。
06:00
从这获取到是哪些convert,是这个convert,而这个convert呢是,呃,怎么得来的?这个convert其实是一个属性,是我们这个HD message converts,只要这个构造器一创建对象就来的,而创建对象的时候呢,它里边大家会注意,它里边呢会添加一些默认的convert and devo,最终把这个默认的convert,然后呢复制给这个converts的,所以默认的convert有哪些,我们可以点进来看一下,这是获取默认的convert,然后呢,这有默认的convert,默认的L又是从这拿的点进来,然后呢,在这一块呢,又有添加默认的,你就一直点进来,你会发现系统底层的C其实就在这,哎,这就解释了我们为什么系统一启动底层呢,有这么多bit string http,还有RESOURCE1大堆,其实就在这by string resource这一大堆,所以呢,我们这有这些默认的message convert,在这有这些默认的message convert。
07:00
而且还有一个最比较神奇的写法,就是如果我们导了扎克son的这个插麦的处理,它呢也会导入插麦的这个自动导,导入插麦的convert插的convert,我们都知道叫map扎son to插mer HT message convert,再来看一下map Jackson to插麦HT message convert它是怎么被导进来的,其实很简单,它这呢主要判断它为正,就给所有的message convert集合里边添进来,它怎么为正点进来,你就会发现这呢是一个静态判断,这个静态判断呢是用类工具,只要看你的这个系统里边导了这个类就行了。所以呢,这就解释了我们为什么是我们导了扎克son的插麦尔处理,我们扎克son的查麦尔的这个卡沃就会自动进来啊导,导入了扎克son处理插麦的包,扎克son处理麦尔的包,麦尔呢的卡沃就会自动进来。
08:00
怎么自动进来的,它的这个源代码呢,就在这一处,我们正好说到它了,那么就给大家拿过来这儿呢,它是在这判断X的这个包,这个类是不是存在。是不是存在,然后呢,这个呢,都是在我们这个类里边。我们都是一步一步点进去的,然后呢,他判断如果存在了,大家会看到把自己呢,他会把这个东西填进去,你看一下它的这个引用啊。那这个引用引用呢,在这判断。判断好,只要判断你的这个存在,那就会给你添进去,只要判断我们这个东西呢,系统类里边有,那我就会给所有的message convert里边添一个man,好,那既然解释了我们系统里边默认已经有一些了,我们想要支持自定义协议,那我们就得添加自定义的message convert,自定义的message convert怎么填?我们说了一句话以后呢,无论我们要改spring l VC的什么功能,Spring l VC的什么功能,我们都是通过一个入口改一个入口,哪个入口呢,默认都是通过,这在spring boot的官方文档里边,我们之前就已经说过,想要定制spring MC的功能,你呢,只需要给容器中放一个叫web mvc con菲这个组件,在这个con菲里边呢,你定制好是什么就是什么,所以呢,我们自然而然在这个web mvc康菲克这是一个接口,它里边呢就有一个我们往下翻。
09:36
叫config message converts像配置我们的消息转换器,还有一个叫extend,这两个有什么不同,配置的话呢,相当于会把默认的都覆盖掉,而extend呢,这就叫扩展,所以你默认的还有我给你额外扩展一些,所以呢,我们现在想要用的扩展功能,我们只需要在这叫extend messages,所以呢,大家一定注意,我们想要呢,配置也非常方便,一个入口就是呢啊,给容器中,给容器中添加,给咱们这个容器中添加一个这个东西叫web mvc con菲就行了,然后你在这个里边呢,你想改spring mvc的什么东西啊,你改完配置它都能应用生效。
10:26
来点进来,所以呢,我们现在要做的就是修改message convert,我们不是修改,我们是额外功能的添加,所以呢,我们现在要做的就是来填一个自定义的message convert能实现什么?把我们的这个person对象,然后呢写成自定义格式的这个数据,而自定义格式的数据呢,我希望是什么?那杰森呢,写杰森插写插面,我自定义格式的数据呢,我就希望是这种格式,把所有的属性的值,把P对象的属性值一,然后呢跟属性值二以分号呢隔开属性值啊这样呢做的好处就是大家会发现我的这个自定义,我光把值要来所有的这个比插麦尔和杰森又省了很大的这个,呃,数据量的占用,它传输起来就更快了,好,所以呢,这是我们的整个。
11:21
整个的这一块的,呃,我们的要求,我们希望呢自定义写出这样,那我们呢,就必须添加一个自定义的什么什么convert,所以呢,我们现在就先来做第一步,我们先来编写出我们自定义的converter,我呢就直接啊我们来把这个converter呢,我们还是放在一个包下吧,Convert convert好,我们现在呢有一个自定义的message converter,我们就叫呢硅谷来,我们硅谷协议的message convert convert好,我们的这个message convert,他让他来实现谁呢?Http message convert count,这是message count总接口,它能操作什么,比如呢,我们这个硅谷呢,就支持我们呢全市,呃我们这个硅谷类型的,呃这个数据怎么叫全是硅谷类型的数据,假设呢,我们就是person吧,好,假设呢,我现在就支持操作person,然后呢,我来回车把所。
12:21
获这个方法我们都填上,这是我们自定义的convert,自定义的convert convert,然后呢,这个自定义的convert填上以后呢,这几个方法,首先第一个叫can read can read的意思就是我们呢,能不能把某个类型,把person类型的数据读成某种,哎,我们坦瑞呢,我们都写为false,我们不支持读,所谓的支持读就是比如我们传来了一个person数据,然后呢,我们用request body来标注,哎,你给我传来的呢,是Jason,或者是插,或者是自定义类型,那我们呢就给你读,所以我们说message count,因为它两种功能,能读能写,所以我们现在呢只关心写逻辑,所以读呢,我直接返回false,能不能写啊,我就直接返回出只要,哎我们也不直接返回出了,只要你的这个class啊,只要你的这个啊,你你的这个方法返回的这个值类型是我们这个。
13:21
类型啊就行了,对吧,只要你呢是这个person类型,我就能给你进行读写,然后呢,接下来我们在这呢,包括我们来获取,我们注意咱们这有一个叫获取所有支持的媒体类型这一块非常重要,因为我们知道内容协商里面有一个最关键的环节,就是我们服务器要统计,服务器,服务器要统计,要统计所有message converter到底都能写出哪些内容,所有message convert都能写出哪些内容,能写出哪些什么这个内容,呃,内容类型,所以呢,他想要统计就是调用我们这个叫get support media types,我们把每一个message convert能嗯兼容的这个媒体类型全部统计集合起来,所以我们在这呢,就得告诉我们spring l VC,我们这个message computer能干嘛,我们这个message computer呢,相当于要能操作我们的自定义类型application。
14:21
K,什么啊,就是X硅谷这个类型,X硅谷类型,所以呢我在这,因为X硅谷呢属于自定义类型,我们在这儿呢,比如大家看media type里边,人家规定的这些类型啊,杰森啊这些啊肯定不行,所以我们自定义类型呢,可以用人家这个方法叫pass media types,大家注意我们用这个,因为他呢要求返回一个我能支持的类型集合,所以只有这个方法呢,返回的是集合,让他呢帮我们把字符串解析成我们的这个媒体类型集合,而我们的这个字符串呢,就叫application,这是我们自定义类型X硅谷,好,然后呢,接下来read我们就直接返回,那而right呢,我们现在就是自定义协议,协议数据的写出,自定义协议数据的写出非常简单,Data就是呢,将我们里边的每一个属性点get username,呃,跟这些啊。
15:21
分号拼接出来就行了,好,我就来拼上两个意思,一下get h,比如我们再来拼一个get birth加get birth,好,这相当于我准备好了自定义类型的数据,然后接下来怎么办呢?我把这个数据来写出去,所以呢,这有一个output message,我们会看到output message,这就是我们能写出的数据,这不就有一个get body吗?这这个body呢,这就是一个输出流,所以呢,我们接下来就要将我们的这个数据写到这个流里边去啊,Body里边去,所以body right right什么东西呢?把我们这个东西写出去就行了,Date。
16:06
点get bits,好,我们把它写出去就行,所以呢,我们相当于把整个数据呢,全部啊就写出去了,写到我们这个响应里边,这是我们说的自定义类型的这个convert,而自定义类型的convert我们要添进去,就是通过这个extend来填的,我们在这converts点一下,点and添,添一个我们的convert,我们的convert呢,我们就直接扭过来,你有一个叫什么呢?我们现在叫硅谷,硅谷我们的message convert,好,我们把这个一填进来以后呢,我重新debug,我重新debug看一下我们现在能不能要到我们自定义类型的数据,那还是这个方法,一模一样的这个方法。我们能不能要到application X硅谷类型的数据,好,那么现在呢,以debug模式进来,那还是要person person呢,现在我们先要杰森啊,杰森呢,我们不测了,你现在直接测X硅谷杰森这些都可以X我们现在硅谷,好我来点一个send来,请求一发出去,请求发出以后来到我们这个内容协商的这个流程,好来到我们这一块的内容协商来看一下啊好,现在呢,开始来进行,诶我们来这一块呢,放行的有点多了,我们来重新,重新来,我们来看到呢,诶这个数据已经返回了啊,没问题,要是能拿到这个数据,为什么能拿到,我来给大家send一下,看一下,就因为这样才能拿到,好我们来准备要内容协商了,我们来进来,好,他在这来处理,处理得到返回值好,他准备内容协商,内容协商以后呢,接下来关键的第一点,首先获取我们这个客户端能接收的内容类型,而客户端能接收的。
17:56
内内容类型呢,它是使用content negotiation manager,相当于我们这个内容的这个处理器,而这个内容处理器呢,因为我们是以请求图的方式,所以呢primemeter方式我们没有管,所以呢,他最终通过拿到请求投里边的东西,最终得到我们要application X硅谷,然后呢,接下来它在统计我们服务器里边所有能产出的这个内容类型来,Step into进来,它怎么统计呢?其实就是我们说的这个环节,将所有的message convert,我们来看所有的message convert里边就有一个硅谷message convert,它调用所有的message convert,然后呢,调用它的can write can read方法,看能不能读,能不能写好,我们一直来,我们来看它现在轮到哪个count了,叫resource,大家注意观察它。
18:44
Resource现在呢,又变成了别的啊,我们再继续走,这个叫O,我们现在来变成只有我们这个自定义的,大家看好啊,我们现在自定义的convert,好,大家看我们这个自定义的convert沃呢判断成功,因为它一直啊,它的这个判断呢,非常简单,们自定义的convert的判断就是说只要你是person类型的,只要你是person类型的,我就能支持读写对吧,Person类型的,所以呢,那我们现在呢,现在确实我们是person类型的,然后呢,接下来再来调用我们返的这个media type方法,我们来step型图给大家看一下,看,这就是我们convert返回的这个媒体类型,最终呢,把我们这个媒体类型填进去,所以呢,整个系统出来以后呢,就统计出我们系统里边所有的卡沃能能合起来生产这么多种数据,但实际上呢,实际上我们能生产这么多数据,而你要哪种数据呢?人浏览器要呃开成X硅谷,所以呢,接下来来到最佳。
19:45
配内容协商最佳匹配以后呢,最终匹配到我们浏览器要X硅谷,那我们就给浏览器写X硅谷,好,我们来看一下,最终呢,我们这个media type to use,那就是写X硅谷,既然呢,我们知道我们现在要把数据写为X硅谷这个格式,那接下来怎么办呢?接下来就来便利所有的message converts,然后呢,看一下每一个message convert,谁能支持操作这个媒体类型的数据啊,那接下来呢,就是我们自定义的了,那就直接来给大家放到这吧,If判断接下来这个message count string不行,然后呢,接下来呃,来到resource,这个也不行,然后呢,谁可以,那也不行,我们来看啊扎克son也不行,扎克斯呢,他的判断虽然是能读写我们person类型,但是他不支持把person读为我们指定的这个媒体类型,就是读为我们这个X硅谷,所以呢,Jack他的这个肯定能进去,但是呢,来看一下啊。
20:45
它的第二个这个判断就进不去,所以呢,它这有多重判断,你虽然呢能支持操作这个数据,但是还要看你能不能支持这个数据转为这个媒体类型,所以呢,我们现在一直放行到我们自定义的,自定义的自定的来看一下,自定义的诶自定义的我们给放过去了,放过去的那一不小心放过去了,但是呢,如果实际上我们来给这把断点打到这儿来重新来看一下吧。
21:16
来重新来看一下send,好,来重新来看一下们来注意观察,我们现在呢叫resource,现在呢叫resource,现在叫or?现在叫map Jackson,现在map Jack Jackson,好,现在叫硅谷man convert,那就是他了。好,接下来硅谷message convert它能操作,他能操作以后呢,接下来拿到body,所谓的这个body就是我们方法的返回值,目前还是一个person对象,接下来呢,就调用我们自己的这个convert的right方法,Step into,我们自己的方法呢,就是将对象写为我们自定义协议数据,最终呢写出去啊,我们最终呢,最终就想应出我们是自定义类型的数据,而你想要杰森就是杰森,想要什么就是什么,那现在看一下杰森也可以send。
22:06
好,我们现在来确定一下,放心放心,放心放心,哎,我们也不用管它的源码了,看杰森也能写,自定义也能写,插麦也能写,这就是我们通过基于请求图的方式,哎,我们进行内容协商能写多个数据,那现在呢,给大家留一个呃,留一个呃作业,我们这个插麦也能写,留一个什么作业呢?我现在呢把它以非以非得8UG模式起提起来,留一个什么作业,就是我们的这个person啊,如果我们请求投的方式,那我们三种都能写,但我们看能不能以我们这个相当于浏览器能实时切换的这种方式,以参数的方式来进行内容协商看一下啊,如果我来写接S走它能写,如果我来写差那走他能写,那现在问题就是我们自定义协议数据这块写啥,所以呢,我们接下来给大家留一个作业。那如果我们是用。
23:07
URL这个参数的方式,我们如何来进行继续来进行内容协商,所以我们现在呢,已经测试通过这块内容协商没问题,然后呢,我们的作业来先考虑一下,我们下节课再来说就是如何以参数的方式进行内容协商。
我来说两句