00:00
好,下一个步骤呢,我们就来去把我们的文件上传业务呢,去给它做一个实现,那我们的文件上传呢,我们先创建一个file service接口,然后在file service这个interface接口里面呢,我们先创建一个抽象方法啊,所以我们先做这件事情。好,那么在OS这个下面呢,我们创建一个package,叫做service,好,那么在这个service下面呢,我们创建一个Java class,选interface,然后呢,它叫file service,好,然后接下来呢,在这个呃,In service下面呢,我们选择package啊,再写一个ipl,对不对?好,然后在这个MPL里面呢,嗯。我们再写一个实现。叫file service ipll,然后呢,我们让他去ipll对吧,给他改一下啊,右键rename。
01:03
对,好,然后呢,我们让这个ipl呢去implements,刚才那个fair service,接下来呢,不要忘了在这个位置呢,去写一个at service是不是先把架子搭好,然后接下来呢,File service里面呢,我们创建一个接口啊,这接口咱们先来复制过来。这接口呢,就叫文件上传接口,然后它呢接收三个参数,这三个参数呢,分别是input stream类型的数据流啊,也就是说我们真正上传的文件呢,要以这种输入流的形式呢,要在这个service当中进行一个啊这个赋值,然后接下来呢,Mo Mo的话呢,未来我们在上传文件的时候呢,可能会上传各种各样不同类型的文件,比如说上传这个借款人的身份证信息啊,上传他的房产信息,上传他的车辆信息等等啊一系列审核他啊这个借款额度的啊相关的信息的这样的一个文件,那我们呢,希望未来这些文件呢,都分别存储到不同的目录下,所以呢,我们就把它们定义成不同的模块,叫modu,当模块不同的时候呢,文件就会存在不同的目录下啊,然后这个file name呢,是我们上传的文件的一个原始的文件名字啊,我们把它拿到,这样的话呢,便于我们后续做一些。
02:25
进一步的处理,那这样的话呢,就是我们。接口中抽象方法的一个定义。Out加enter。我们把这个实现一下啊。好在这个里面呢,我们就有了一个嗯方法了,然后这个方法里面我们写什么呢?就写文件上传的过程,那文件上传怎么传,肯定也不是我们自己,嗯,就是硬想出来的,那肯定要看文档,那么来看一下这个文档啊。
03:00
好,这个文档里面呢,有一个嗯OS呃,就是之前我们的帮助文档哈,我看一下啊,我们的帮助啊,这呢这个帮助文档,这个是上午我们看的这个帮助文档,对不对啊,我们再回顾一下这个帮助文档怎么进来的啊,因为这个帮助文档确实不太好找,我先领着大家走一遍,就是首先呢,你登录了之后呢,先点控制台。然后我还得重新登录一下。好,现在呢,我们来到了控制台的首页,在这个控制台的首页当中呢,我们选择这个对象存储oss。那么在对象存储oss这个地方呢,我们看右侧。右侧啊,这块有个常用入口,那我们呢,可以在这个地方呢,选择我们的文档,那之前我们是选择了Java学习路径对吧?然后在Java学习路径当中呢,直接选择了Java SDK啊,这样是可以的,那同时呢,你也可以在这里面直接点API文档或者是啊开发指南都可以啊好,然后接下来呢,我们进来之后呢,我们就。
04:15
还是要看一下我们的这个文件上传业务的文档在哪找,那么这边呢,我们有SDK示例,有Java,然后这边呢,有一个叫上传文件啊的这样的一个菜单,我们把它展开,这里面呢有很多种上传方式,我们呢先选择这个简单上传好。在简单上传里面呢,有几种上传方式,一种呢叫流式上传,一种呢叫文件上传,那么我们呢,选择流式上传啊,因为我们要。用那个输输入流是吧,去接收那个文件对象,所以呢,在这个流式上传里面呢,它有上传字符串,上传字符串肯定不行啊,就是一个字符串传到服务器上,这肯定是不行的,上传BI数据,这也不是我们要的上传网络流,就是从网络上加载一个图片,然后上传到我们的啊oss服务器上,但是我们呢,实际上是想从本地上传,从本地上传的话呢,我们就用这个上传文件流的方式,上传文件流的方式为什么符合我们的要求呢?因为它这个地方呢。
05:18
直接是input stream对吧,它是可以去啊,这个通过接收就put object核心方法在这啊,通过接收input stream,然后呢,来执行一个文件的上传,正好我们在定义接口的时候呢,我们这面呢,就定义了一个input stream类型的这样的一个参数,那这样的话呢,我们正好可以把这个音频的参数复制到这个位置,对吧,作为我们上传文件的一个文件流啊,所以这块呢,是我们需要的这样的一个代码,那我们把这个代码复制一下吧。然后我们找到我们的阿里云。找到S2B啊,找到S2B之后呢,我们在这个地方呢。
06:01
我们把刚才复制的代码给它粘贴过来好。那现在呢,我们就需要来对我们整个的啊这个代码呢,进行一个改造,首先呢,我们是。明确一下endpoint啊的地址,那我们呢,在啊前面其实已经对这个endpoint进行了一个常量化的设置了,是不是啊,所以呢,在这个地方啊,我们呢就不去取这个值了,我们呢就直接呢取取我们刚才工具里面的那个定义的常量oss properties.and point,好,这是第一个啊,第二个也是一样的,我们就不用这个SPI了,我们直接呢就是OS proper.access.kidid对吧?然后第三个呢,就是access key secret,我们也不需要它了,把它删掉,然后这面呢,我们就写oss properties.key secret啊所以这块呢,就是这三个参数,好这三个参数写完了之后呢,我们这面呢,就可以上进行这个文件里的上传了。
07:12
然后文件流的上传这块呢,它呃是有一个input stream,但是我们的这个input stream呢,是不是都嗯都传进来了,所以就不用我们自己去扭它了啊。所以直接把这个input stream放在这就可以了,所以这块是我们上传啊的一个过程,然后接下来呢,就是bucket name bucket name的话呢,我们也是一样,从我们的oss proper,然后点buck name这个地方啊去获取就可以了,好,然后接下来呢,我们来看一下,最后这块是关闭啊,关闭完了那就shutdown了,最后这个return呢,一会我们再说返回什么这个把object name呢,也是一会我们再处理好,现在我们要处理的是什么呢?我们现在要处理的是这个8NAME这块。啊,我们在执行文件上传之前呢,首先要确保这个8K的是在的,对不对,如果这个8K的不在的话。
08:06
那么你这个直接往这个八字里面put文件呢,就有问题,所以呢,我们先确保,我们先确保这个八字的存在,所以呢就是判断。好,接下来呢,我们来看一下if,之前咱们学过的就是oss plant.does buck exist,然后呢,我们把oss properties.buck name呢传进去,如果它不存在,我们就创建一下,如果它存在我们就直接用,这是不存在,不存在的话呢,我们就oss client点2CREATE buck,然后呢,Oss proper.bucket那里啊,不存在就创建,然后接下来呢,就是OS client.set bucket。
09:10
ACS client properties.buck name,然后呢,Hand access control list public read啊设置它的这个访问权限呢,为读写权限啊,所以这是不存在的情况,那如果存在呢,就直接往下来了,直接往下来了呢,我们就上传文件里关闭,当然了,在整个上传的过程当中呢,我们说啊,如果你直接就把这个文件的名字,比如说这个相当于我们的一个文件的名字了。放上去的话呢,那么我们上传呢,它是直接上传到,嗯,直接上传到我们应用程序这个bucket的这个默认路径下哈。所以呢,我们希望它上传到什么路径下呢,我是希望它上传到这样的一个路径下,在我们的。
10:04
Oss管理控制台这个地方。好,假设说我希望他放上传到AVA这个目录下,或者呢,我上我上传到一个指定的目录下,这个指定的目录是什么呢?这个指定的目录呢,假设说就是这个猫,那这样的话呢,你上传的这个路径的位置呢,就应该是猫加上。加个杠啊,这个是路径是吧,啊文件夹,然后路径,然后文件名应该是这样的一个地址了啊,所以呢,我们这个这块的这个地址呢,我们干脆给它拿出来定义成一个变量。好,那这样的话呢,我们就会上传到这样的一个目录下,那上传到这样的一个目录下呢,一般情况下也不是一个最优的解决方案,一般我们都会怎么做呢?我们都会就是把这个呃文件呀,因为有一些大型的系统,它每一天可能上传的文件比较多啊,为了便于管理,那一般情况下呢,我们会把当天的文件呢,放在当天的独立的一个目录下,比如今天是五号就五号的目录下,今天是六号就六号的目录下,那一般情况下呢,这个目录结构呢,我们会这么创建哈。
11:31
那就是这样的,比如说。比如说这个model啊,它的这个值呢,是这个AVA,那么我这个文件的目录结构呢,就应该是A,然后杠。2021杠。今天几号?2021是吧,0227啊,0227啊,然后这是目录哈,在他下面呢,有个2021的目,然后下面有个零二的目录,下面有个二七的目录,然后下面才是当前文件的文件名字啊,那么。
12:18
当前文件的文件名呢,一般情况下我们也不用这个原始的,原始的这个file name,因为这个file name呢,是啊,大家想一想,这个是我们的外部,呃,这个服务器端的一个service,那未来我们还得写一个controller来调用这个service,对不对,我们怎么调用那个controller是不是在前端调用啊,前端怎么去啊,给后端一个文件流啊,是不是用上传文件的方式啊,对,所以呢,在上传文件的过程当中啊,用户选择的那个文件的原始的名字就在这儿会被传递过来,那么我们一般情况下呢,不会把用户这个本地文件的名字呢,直接存储到我们的oss当中,因为用户本地文件的名字它是不可控的,它写什么都可能,对吧,有可能会出现一些乱码的问题啊,就是特殊字符都有可能存在,所以一般情况下,我们接收完用户本地上传的文件之后呢,都不会用它的原始名字,都会给它起一个名字,而这个名字呢,比如说我们可以用类似于随机数的方式,像UUID之类的方式啊,然后给这个。
13:17
呃,文件起个名字,然后再加上文件原来的扩展。文件原来的扩展名是啥,你取决于这个参数啊,取决于这个变量,这个变量最后扩展名的部分它是啥,那么我们这个文件的扩展名就是啥了,对不对,比如说是JPG啊这样一个扩展名,所以最后呢,我们其实是希望能生成这样的一个目录结构的。然后呢,作为这个T啊,也就是说我们要包含这样几部分的内容,就是这是属于哪个业务的文件,然后呢,这个是哪一天上传上来的啊,然后呢,这个文件我们动态生成的文件的名字以及扩展名是什么,所以接下来的一个步骤呢,我们要做这个内容,对吧?这一部分的内容呢,给它组装起来好,那所以啊,这个好办啊,这个这个这个东西,这个就是我们举的一个例子,那实际的情况呢,我们用model来表示,就是呢,它会通过这个参数来传进来,所以这个就已经有了,那我们来看一下这个部分的内容。
14:13
这个部分的内容呢,需要我们生成一下。好,怎么去生成呢?前面呢,我们在引依赖的时候,引进来一个叫做time的依赖,就是它,它呢是时间日期格式化的一个工具,我们用它呢去对当前的时间呢做一个格式化,怎么去格式化呢?就是new date time。New time啊好,我们选择第二个招time里面的这个,然后接下来呢,点to string。这个to string啊好,然后这个兔string里面呢,它可以接收一个参数,这个参数呢就是patternyon,就是格式化字符串,比如说我们的patternon呢,是YYYY-MM-DD,好这个呢,就是一个时间啊,日期类的这样的一个格式化字符串,那么因为我们这个是要做最后的路径的,所以呢,我们可以把这个。
15:15
值作为字串的形式返回回来,那么它呢,比如说你可以把它叫做嗯,Time folder,就是基于时间日期的这样的一个,呃。文件夹名字好,然后接下来呢,我们在这个地方呢,就。啊,我们的key呢,就等于model加上杠啊,再加上这个time folder,然后呢,再加上这个杠是吧,再加上内膜,当然了,这种呢,你也可以给他改造一下,怎么改,就把这两个杠啊。签到这也可以,这样的话,这个路径不就前面有杠后面有杠了吗?那这个时候你你这块就不用写了,就省点事了哈,前面这个time folder本身就是前后带盖了,好这样的话呢,我们就组成了一个路径,但是呢,这个只是针对文件夹部分的呃,内容做了处理,针对文件名呢,我们还没有处理文件名呢,我们是想这样,因为刚才说了,嗯,不应该把原始的文件名直接存储起来,因为它风险比较大,有可能乱码什么的,所以一般情况下呢,我们会根据原始的文件名啊,生成一个新的文件名,嗯,并且呢,把原始文件名的扩展名拿到,所以呢,这块呢是。
16:31
文件。文件名生成啊,那怎么写呢?我们用UUID啊,一般的策略呢,就是生成一个随机数random u u ID,然后点to,好,这个是名字的部分,接下来呢,我们看扩展名的部分,画名的部分呢,就是还是这个file name。点subst顺啊,就是截断对吧,截断啊从哪开始截呢?我们就从那个,呃,扩展名吗?扩展名就要点什么什么是吧,比如说我们有一个文件。
17:10
扩展题叫Helen点接接PG啊,那你截的时候你是不是就从点开始截就行了,因为它截的时候啊,当前这个指定的这位不算,所以从点后面开始计算啊,那么我们就看一下点的这个索引是什么,所以呢,就file name.subs string啊,然后呢,接下来呢,就file name.last index of这个点,先把点的索引给它拿到啊,然后从点的索引这个位置开始往后截,一直截到最后就是我们的扩展名,从点的位置一直往后截,一直截到最后就是我们的扩展名,对吧?啊所以通过这种方式呢,我们是能够拿到文件的,嗯,扩展。棉的啊。嗯,然后我看一下啊。
18:02
所以这嗯,这个地方呢,拿到的是扩展名,然后这个地方呢,我们拿到的是文件名,对吧,生成了一个文件名,然后最后呢,我们把它复制一下,嗯,比如说就叫做内吧,把它。大家重新的复制一下。好,现在呢,我们就有了这个file name了,然后也有了key了,然后key呢,是由time folder加上file name对吧,共同生成的,然后最后呢,我们就把这个。File name呢啊,我看一下啊,作为我们的文件上传的一部分地址放到了key里面,然后这个key呢,最后呢,就作为我们put object其中的参数之一,被复制到我们的这个啊put object这个方法当中来了,所以呢,这样的话,我们的文件上传功能呢,基本上就。做的差不多了,当然了,是业务层啊,是业务层,我们再来看一下我们都做了什么,首先创建plan实例,第二判断bucket是否存在,第三啊,如果bucket存在,那么就继续往下执行上传啊,如果bucket不存在,那么我们就先创建这个八,并且设置它的读写权限,然后接下来我们在这个里面,如果真的去执行上传的话,我们需要呢?啊,考虑的就是这个key啊,怎么去生成那这个key呢,实际上就是整个的这个文件在你服务器上面的路径啊,也就是说除了主机地址和端口号之外的路径,其实呢,都包含在这个key里面啊,那所以呢。
19:37
这个key呢,就由model time for到name啊来组成,这个呢是我们的啊模就是模块是吧?啊,那这个呢,是我们的基于时间的这样的一个目录结构,而这个呢是我们的文件名,当我文件名有两部分组成,一个呢是原始的文件名字,把它去掉,然后用UUID生成,另外一部分呢,就是原始的文件名字后面的扩展名,我们把它取出来,和前面的UUID呢,给它做一个拼接啊所以这块呢就是我们的业务层的一个实现。
我来说两句