00:00
那刚才我们给大家简单介绍一下,用Java啊,Java来生成一个套文件。好,那我们他这个生成文件生成的时候,因为Java是运行在后台服务器上的。所以它生成的文件一定也在后台服务器电脑上面,就像我们建这个目录,我们就模拟一下,他就在后台服务器上面。生成的这么一个文件,那用户想拿到的话,那用户肯定要什么把这个文件拿到他自己电脑,如何拿到电脑号码,那你得把你Java生成的这个文件还要能够下载到用户自己电脑。那用户自己电脑,你比如说大我这个地方创建一个简单一个目录,这个目录假如我就代表用用户自己的电脑,我这个地方假如就叫电这用户自己的电脑,那他想拿到他得下载到他自己电脑才行,那如何下载,那就是加到这个文件来下载。好,下面我给大家简单演示一下这个文件的下载到底怎么去做。
01:00
这是我们这个文件下,那文件下载,那我们首先来看啊,它这个它这个大体上它这个业,它这个业务或者他这个流程基本上就这样,其实也很简单了,怎么简单,他就这样,那用户想拿的文件基本上就这样,他要向后台发下载的请求,怎么下怎么怎么发,那他什么就点一个按钮就行了,就像我们这地方页面上肯定有个按钮。大家平时在网络上你肯定也会下载一些文件,那你下载文件的时候,大家也有这种使用经验,那么什么就是在什么你一个网页上面有一个什么按钮上面写个下载,然后或者是一个超级链接,你一点好他就下载了,其实就像后台发起文件下载请求了,下载请求怎么了,后台有CTRL处理出来处理怎么再什么执行的CTRL时候到服务器磁盘上面去读那个文件,读完之后怎么通过流输出的浏览器。然后呢,你的浏览器你点它你就收到这个文件了,收到文件怎么了,文件下载跟什么,跟普通的这种请求不一样,文件下载的时候,它不是说把这个文件显示到窗口上面干什么,它是弹出来那个什么下载窗口另存为知道吧,这样的话你一存诶这个文件就下载了,这基本上这个流程就是这样说,用户1.1个呃一个按钮,或者1.1个超级链接,向后台发文件下载请求,后台CTRL接收到之后,到磁盘上,服务器磁盘读一个文件,通过流输出的浏览器,然后输入到浏览器之后,自动的激活那个文件下载的窗口。
02:37
然后呢,然后用户什么就拿着看到这个下载窗口了,然后就点1.1个另存为就存起来了,这样就下载就完成了,知道吗?好,下边呢,我们对他这个流程有个大概了解之后呢,下边我们准备给大家简单写一个例子,让用户是吧,在页面上能够下载我们的文件,下载哪个文件,咱们就咱们就让他下载这个文件,假如说这个文件我在服务器上生成了,那么用户是呢,想拿到这个文件,他就要下载,怎么下载,从打开我们的页面,他1.1个按钮,发一个文件下载的请求,那我后台把这个文件读出来,通过流输入和浏览器,它就下载下来了,所以我们下边准备来做这个事儿了,那来做这个事儿,我给他演示这个例子啊,那我们要做这个功能来看。
03:22
那那什么这个时候他就牵扯到前台和后台了,前台用户发文件下载的请求,后台处理,处理完之后反正做出相应信息知道吧,所以说那那这个地方我写这个例子的话,就不是纯后台技术了,文件下载的请求属于外部技术,它既有前台又有后台,所以我们这个地方,那我们要提供什么,我们要写这个测试程序的话,既要写前台页面,又要写后台的同步了,所以我们这个地方来一会儿我给他演示的,我就准备来给大写这个了,来写一个,写一个页面,这个页面假如说我给大家这个页面名字,我随便随便命名一下,就叫fire,叫给大家演示文件下载的叫fire download download download是下载的意思,知道吗?test.jsp,我一会儿准备提供这个页面,这个页面上面很简单,就提供一个按钮或者一个超级链接也行,我就提供一个按钮了,用户一点这个按钮,向后台发同步请求。
04:18
啊,不是不是同步解是吧,是叫发一个导这个什么导出请求,或者文件下载的一个请求就行了,然后呢,发完请求之后,后来我一会提供一个ctrler,那这个controller,这个controller,假如我就在这里边写啊叫activity controller,我就在这里边准备写一个方法,让他处理这个什么处理这个文件下载这个请求,在这里边加一个方法,这个方法我就简单设计出来,这个方法就叫fire download。Fire download download这个方法,然后呢,在这个方法里边来进行什么去执行我们的代码干什么去读服务器上一个文件,输出到浏览器,让用户去下载,去知。
05:02
好一会儿我就准备来写这个了,那写这个的话,那么我们这个地方大看就牵扯到这两个代码,一个是JSP,一个CTRL了,我也不给大家画流程了,而且我开发的时候也不是按照从底层往顶层写,因为这个代码太简单了,所以我就先写页面再写CTR了,知道吧,好,下边我准备这样,在我这个我们还在CR项目边来做我们这个例子了,然后呢,在这里边我提供一个页面,这个页面由由于是测试页面,所以我也写了外部APP里边了,这样测试到时候好方便好测,然后呢,在这个地方右键来创建一个网页,那这个网页来一个就是我们这个网页叫fire download fire download,然后呢叫test JSP,知道吗?然后呢,这个地方呢,我给他演示文件下载,文件下载是吧,然后呢,演示文件下载,他将来要上后台发请求,发到哪个URL上边,得迁到URL,加到URL,我们知道都从base标去找,所以我。
06:02
给这个页面加个base表格,那加base表我就不自己写了,CTRLC拷贝过来,然后呢,直接加上就行了,Base表格好,这样这个页面我就写完了,这页面写完了,那我在上面准备提供一个按钮,我们说我这个页面就是最简单的一个页面,只要能发出文件下载的请求就行了,所以我这个地方准备就这样加一个按钮,这个按钮来一个什么,我们这样来input,然后呢,这个地方来一个type按钮,叫什么button痕,知道吧,然后呢,在这个按钮上面我来显示俩字,这俩字假如说我就叫我下载吧,或者叫载文件都行,知道吧,然后呢,我一会儿要给它加试件,为什么加试件?因为用户一点开要向后台发请求,所以给他加一个试件,加试件的话,那我这个地方呢,我要给他一个ID了,那这个ID假如你我这个我就随便写了,我叫fire fire download吧,Fire download,然后呢,Button这个这个按钮我就提供好了,知道吧。
07:02
好,这是我们说的这个这个网页我就提供了这个网页上面我们很简单,我就模拟这个这个什么这个按钮,用户一点它相互再发文件下载请求就行了,知道吧,好,这是我们说的这样,那这样的话,这个这个按钮有了,下边我要给他加视件了,加视角根据我们以前给他讲的,最好在入口上边统一讲,那这个地方写入口函数,那入口函数大家都知道入口函数是属于属于解块位的,所以你这个地方要引入解块位。所以往这个地方就来引入解块人了,那引入解块RY,解块RY是script加GS代码,所以引入GS的开发包,然后呢我们这个地方来个type来一个,然后呢这个地方来个src,然后呢把我们解块位的路径写大包这个地方来个解块,这样的话大家我就引入解块位了,然后呢在这的方我就可以什么写我们的入口函数了,写完这个地方来个script了,然后呢type,然后呢script了,然后呢这个地方在这里边写个入口函数,那入Dollar了符号啊,然呢在这来一个翻个式,三个式表示,当页面加载完之后,然后呢就会自动处罚这个执自动执行这个函数,我就在这个函数时给我们的元素加视角,给哪个元素加,我就给这个下载按钮,给下载按钮添加单线时间下载按钮添加添加单击事件,添加单击事件,嗯,他一点这个下载按钮应该向后台发一个文件下载的请求。
08:32
所以那给它加事件,那我说加的话用传统的这种方数,然后呢,直接加单机事件,可然后呢,在这里边提供一个参数,这个参数本身是个函数,表示当用户一点这个下载按钮的时候,自动触发这个函数,在这个函数干什么,我刚才给大家说了,用户一点它要向后台发送一个文件下载的请求,发送文件下载的请求,那我在这发送。
09:01
那发送的时候,这个时候我问大家了,这个是同步请求还是异步请求。对,同步的还是异步的?那同步还是异步,是不是我们就看一看响应回来之后是不是刷整个页面,或者是不是要跳转页面,是不是这样子,那我这个文件下载是不是要跳转页面呢。不跳转是不是不是不是刷新整个页面是不是这样的,按理说是不是同步请求。按理会是同,按理会是不是义务请求,对异务请求,但是这个地方大家要记住,所有文件下载的请求只能发同步的,只能发同步请求,大家要记住一句话,所有文件下载的请求只能发同步请求。对,只能发同步所有这个地方,所有这个我我写到这里,写到我们笔记里边,所有文件下载的请求,只能发同步,同步所有文件下载的请求,只能发总同步请求,不能发异步请求,知道吗?
10:09
为什么是这样啊,但你想一想啊,但你想一想为什么只能发同步请求,但你想我们说文件下载的请求,那么响应信息回来之后,回来一个什么,是不是回来一个文,是不是不是回来一个文件呀,就响应这是回来个文件,跟我们以前做的都不一样,以前要么返回网页,要么返回杰森号,现在是返回一个文件,返回一个文件,假如说你返过来想,假如说你要发异步请求,他这个文件会返回到哪儿去啊?是不是要返回到阿贾克斯那个斯了三次后边那个回调函数里边去,那么以前你返回如果发一步请求返问杰森轴传,诶那个回调函数能解析,现在你要访问一个文件,那个函数能解析吗?解析不了那个函数只能解析接近字串,你返回一个文件,它解析不了,知道吗?所以这个地方什么只那么这个地方只能发同步请求,因为响应信息是个文件,如果发异步请求,阿贾克斯发响应信息返回一个文件,阿贾克斯解决不了,所以他只能发同步里头知道吧。
11:22
这时候我们说到这样,那有同学就说了,那老师你发同步请求响应信息回来之后。不就把整个窗口覆盖了吗?大家你再想一想。我们以前发同步请求响应信息回来之后,返回一个接线图片,或者是返回一个什么网页,响应信息回来之后,它会把整个页面覆盖了,为什么?因为返回那些信息就直接返回到这个这个显示窗口上面了。所以它整个页面就覆盖了,但是现在你再想一想,我们这个响应信息返回的是个文件,这个文件我会不会把它显示到这个窗口上面。
12:02
不会,所以他返回的时候,我不让他返回显示窗口上面,我让他返回到哪儿去,返回到下载窗口上面去。所以这个时候你即使是同步请求。显示窗口也不会变。也不会跳转页面,所以这个地方虽然发同步请求响应性,由于给的文件下载窗口了也不会变,所以这个时候的话,从这个角度上来讲,发同步请求也没关系,也不会整个窗口覆盖,知道吧,所以这事我们说了知道知,所以大家记住这一句话,知道所有文件下载的时候只能发土木九。就是因为响应信息是个文件啊,响应信息是个文件,如果E不请求阿贾克斯解析不了。那A解决不了,只能发同步,同步浏览器能解决浏览器怎么解析浏览器?理论上来讲,浏览器应该说什么整个页面覆盖,但由于我们不是返回到显示窗口窗口,而是显示到文件下载窗口窗口,所以即使发同步整个流整个窗口也不会被覆盖。
13:09
所以这个时候只能发同步的知道吧,所以下边我这个地方只能就发一个同步请求了,那发同步请求咋发。对这个地方怎么发一个同步请求。对,咱们前面跟点说了,同步请求发,从客户端向服务器发同步请三种途径,对地址栏超级链接发我表单,这里边有超级链接吗?没有,有表单吗?没有,只有这样地栏,所以那这个要D轮,那地轮在哪呢?对window location所所大看这些理论其实都是一环扣一环,都是有原因的,知道吗?啊你要你要把这些理论反过来调过去,都都应该糅合在一起,是特别熟练的,反过来调过去懂他不管怎么样我们都不怕,然后呢,这个地方点A乘以F发个同步就行了,然后呢,这个地方就可以了,那这个发到哪去?那我我们说我一会要写个CTRL,这个CTRL我就写到市场活动的CTRL到里边去了,啊我为了简单我就写的写,那我要什么,那他这个URL,我一会儿要命名的时候,要和市场活动那些这页面的资源路径包。
14:22
一致,那保持一致,我就直接这么写了,市场活动的那些页面的资源路径就是work win驰那下边提供一个方法,那这个方法资源名称和方法名一样,我一会儿就叫他了,然后呢,角度这就行了,这样的话他一点这个按钮,就像后台发了这么一个请求同步的啊。好,这时候我们说前端这个地方我们就行了,它一点就发一个文件下载的请求,这个页面这个请求只能是同步的,好下边我们来写后台CTRL,在CTRL边加这样一个方法来接收和处理这个请求,所以下边我们写这个CTRL,然后呢,在这个CTRL里边加一个方法。
15:01
按理说你新建一个CTRL也行啊,我这个地方简单了,我就直接在这就行了,然后呢,这个什么CTRL方法,Public返回值返回什么类型。对,这跟以前都不一样,以前要么返回网页,要么返回杰森串,返回网页的时候这个是死病,返回杰森符串的时,这个是object的,现在我既不是网页,也不是杰森字符串,我要返回一个文件,应该返回什么?要定义成什么?为啥盯着杰克啥类型都行?按理说欧布杰克可以啥类型都行,那啥类型都行,大概是这样。大家想一想,我们写cler的方法,为啥定义这个,这个返回值为啥要定义它?定义它有什么用吗?啊,定义成字符串或者定义成有啥用吗?
16:04
我们以前用这个返回值,利用这个返回值干啥干啥呢,这个方法得到的数据让返回,对这个就是什么呢?我们之所以给CTRL方法定义返回值,就想利用它这个返回值,将来把我们要返回的数据是不是借助spring IC这个方法,这个CTRL这个方法的返回值,然后呢,自动给我封装成相应的这个什么跳转网页,或者是封装成阶层字符串,然后把这个字符串返回到响应到浏览器去响应的客户,所以大家跟我说CTRLL从那方法之所以定义返回值。之所以定义这个访问值类型,我们就是想借助他这个control这个方法的访问值,帮我们往客户端返回数据的。不管是跳转网页也好,还是返回阶段字符串也好,我们都是借助他这个返回值,帮我往回返回数据。
17:03
是吧,那如果我要不我不什么,我要如果不借助它这个返回值呢?那你得自己往回反了,自己往回怎么反,就像咱们以前没学MC的时候,通过survey的光辉反馈出去咋反馈的。对,Response拿到流是不是往外写的,往外写的,那之所以后来学了spring FC了,所以我们以后的返回值就借助spring FC这种框架,它的返回值帮我往回返数据,不用我自己response,然后呢获取流往我写数据了,所以我们以前之所以写定义这个反问值,就是既想借助这个反问值让他帮我把响应信息输入到浏览器。之所以定义它这个仿值,就是在于这个目的的,知道吗?啊,那那么定义成什么类型的,那你看一下访问什么类型的,我们以前访问网页跳转页面,访问字符串,然后呢,我们以前要访问阶层,然后呢定义object。
18:02
那现在大厂。我要返回一个人,我要返回一个文件了。能不能借助这个spring MC这个controller方法给我返回一个文件?死,借助这个方法的返回值,能不能给我返回一个文件,大家以前学过吗?借助stemc这个方CTRL方法的返回值,以前我们让他借助它返回字符串,返回网页或者返回字符串都能返回,你以前做过让他返回文件了吗?没有,为啥没有,因为他不擅成,他不上,其实他也能返回文件,但是他不擅长,他返回文件有缺陷,所以一般来讲呢,我们要让什么从后台处理完之后要返回一个文件的话,一般不借助它的返回值。不介入返回,只是帮我返回文件,那你说老师你要返回文件咋办?我自己返回,自己怎么返回啊。
19:04
对,通过response得到流往回返,大家明白这个意思吧,所以这样返回文件的时候,我们一般不介入返回值,我们自己通过流往回返。一会儿我通过流网法,怎么通过流网法,以前大家都学过懂,都学过通过流网反出去就行了啊怎么仿,我一会儿写一下你就知道了,那所以说大家这个文件我一会儿我自己仿,那你说这个法我知定义成什么类型。我不介入它返回响应数据响应信息了,定义成什么类型呢?对,理论上讲定义啥类型的都行,反正他爱啥是啥,我又不助他了,是不是这个意思,对,那所以大家为了那么更简便的话,返回什么VO,我不借助它了是吗?我自己往回返回数据了,所以VO知道吗?是这时候我还说了这所以大家要认清楚每写每一个代码是干什么用的,如果我不用它了,那我就可以不用,我就可以不写它了,知道吧,所以这个返回值我们就想让它返回数据,返回响应信息的,我现在不借助返回值返回响应信息了,我自己往回反了,所以这个返回值就包有了,知道吧。好,下边我来写这个方法名,这个方法名我们已经设计好了,就是它知道。
20:20
好,这个地方来一个,诶这个地方来个,然后呢,这个地方来给他一个request map吧,这里边给他ul这个UR,我说了,刚才我我们已经用了,其实那我这个就我就直接拷过来了啊,然后呢,我这个是测试页面,测试页面这个我就直接拷过来了,我就给它保持一致CTRLC,然后呢,这个CTRL的来拿一下,然后呢,这个地方然然后前面加一个斜杠,这。然后呢,那我们说不借助它返回值了,这个地方也不用加入帮我报备,然后呢,这个地方当我们前台就是发一个文件下载就行,没有参数,不用定义行盘,在这边直接写代码就行了,在这里边写代码干什么?
21:02
就是读我们服务器上面磁盘上一个Excel文件往回返了,要返回一个Excel文件了,那返回Excel文件怎么返,自己往回返。自己返回相应信息。早上。没你代表爱情距离。对,那那自己反过相信,那你就想一想,以前学S的刚一学web的时候。老师教给大家往回返回响应信息分几步?第一步干什么?设置响应信息?设置响应信息叫设置响应类型啊,这个叫第一步设置响应类型,设置响应类型响类型啊,为什么要设置响应类型?那你想啊,浏览器向你发个请求,你要给他返回响应信息,你返回的是啥信息,你得告诉他,你要不告诉他,他打不开。为什么打不开啊,那那你没告诉他是什么信息,他不知道怎么打,所以你必须得告诉我给你访问的是啥,是访问的是A前面网页还是接算照还是还是文件呀,你得告诉他呀,是文件是什么格式的文件,你得告诉他,你要不告诉他,他没法写,他没法解析了,知道吧,其实这种道理就是大家也也也很也很好理解是吧,你比如说你是浏览器是然后你你买一个东西是吧,人家给你返回一个返回一返回一个这个一个一个这个一个东西或者一个商品是吧?那根据你接收到这个包裹,你你敢打开吗。
22:35
你也不敢打开是吧?对,那万一万一是炸弹呢,是就你陌生人给你返回一个什么包裹,给你寄一个包裹,你敢擅自打开吗?你你不你也不敢打开是吧,那他那他你咋才能才能打开,上面给你写了这个包裹是什么是吧?是一箱苹果是吧,那你打开你就知道是吧,你这样你才打开是吧,他如果不告诉你上面啥也不写,给你送一个包裹,你你不敢打开,浏览器也一样,浏览器也不傻,他接入到一个响应信息呢,你也得告诉他是什么信息,他才能打开知道吧,所以你得告诉他,所以告诉他设置响应类型知道吧,设置响应类型咋设置。
23:18
对,找那个response是吧,Response,那找response这个地方是不是注入response http sorry response然后呢拿response,然后呢,这个response,然后呢,各设置一下点它里边有个方法角S的type,知道吧,以前我们返回网页的时候,这里边写上了对,是个A,是T的一个PAPA叫字符串,就是个at字符串,然后字字符串里边有一些字符,采用什么编码,是不是还得设置一下对叉set,然后我们统一都是什么UT嘛,这是以前这么设置的,告诉浏览器我给你返回的是个A,天猫的一个什么网页,诶,它就打开了,知道吧,那你现在返回的还是网页吗?
24:04
不是了,不是了,你就不能告诉他是网件了,你要告诉他你这不是骗了吗?你返回的是什么Excel文件了,那这个地方写什么?对,写这个东西application application叫应用,叫应用程序产生的一个文件,产生的什么文件叫O杠,叫什么stream啊,返回的是一个应用程序,返回一个二进制文件,叫二进制Excel文件,叫二进制文件,没有格式的文件,将来你就按它打开就行了,那他怎么打开,这你就不用管了,这是浏览器的事儿了,知道吧。好,这时候我们说到这,这时候我们要访问Excel文ex Excel文件你就写它就行了,你要访问别的文件,你可能访问,你可能你你可能什么还得写别的呢,那你说老师,万一他下载不是exl文件,他下载是一个什么Java源文件,或者al网,或者一个什么JSP文件,或者是其他的视频音频怎么办?那这个这个地方你就就别告诉他是个Excel文件了,你得告诉他别的类型吗?那不说别的类型还有什么,还有好几百种吗?啊几百种就是我们说这种,只要是你电脑上能够什么写的那些文件都可以下载。
25:18
你都可以每一这种类型的文件都对应一个什么这么一个content的态度,呃,你说老师我怎么能知道呢,你查就知道了,这是协议规定的吗?哪就你查一下,你看看哪个地方看看这个。随便来一个,看哪一个,这对照表,看对照表吧,看吧,这各种各样的文件,这是文件,你要返回的文件后缀名,这是我们的康定的态度,他好像一列还没想完,这是两列,你道吗?你看啊,我们以前就学了一个,我们以前学的是哪一个呢?HTML网页,HTML网页谁能看找找就这个,这是你们以前学的看。
26:02
这这是什么文件,这我这咱咱们也没用过,当这是这是什么图片啊,别人要想下载一个图片,那你就写这个,还有个什么各种各样的图片,还有这图片看吧,还有GSP也可以下载,GSP网页也可以下载。对,还有别的,还有这啥这啥这啥他都不认不认识了,对叉L是吗?还有这这是啥,这也不知道啊,还有一些视频,视频音频等等,反正只要你在文件里边都可以啊,都可以这些。只要是在,只要是你在电脑上能生成的那些文件,都有这几百种吧,一共。还有视频,视频在哪呢?对,这视频音频什么之类的,这些都有。啊,就不找了,不找了,这个到时候你用到这里边去找就行了,知道吧,所以这个地方我们就可以了,告诉他我返回的是一个是吧,Excel文件了,这是第一步就是着了下边的那已经告诉了第二步干什么呢。
27:14
对,这个时候呢,告诉他是什么,这个时候你就可以把把你的什么Excel文件,然后呢往外写了,那往外写怎么写,通过输出流写,所以我们第二步获取输出流,获取输出流,那获取输出流咋获取对response.get什么对write,然后呢,他得到一个叫什么对print write什么啊这个然后呢,这个地方这样就行了,好当然他会抛异常是吧,哎,为了抛异常抛异常我为了代码更更紧凑,我就直接往外抛了,我不处理了,知道吧,好这让我这当然这个流大家你会发现print write write什么有写,而而且是什么字符流,是不是这样子,以字符为单位往外写。
28:07
我们的字符流只能往外写什么文本数据,字符串数据,我们这些数据是字符流吗?对,是以字节流,我们这文件是以字节为单位来存储和传输的,所以字符流我们以前学过,只能写以字符为单位存储的这些什么文本文件,它不能写二进制文件,那我现在要往外写二进制文件,你就不能用这个流,对,用哪一个流?字节流吗?字节流从哪取?对,还是它,还是它,它不但能获取字节流,还有一个正正好,它里边还有一个方法,也是个输出流,叫什么?对,Outut spring,这是以字节为单位往外写,这是我们这道,所以说大家注意response,这是外部文章,它既有可以往往写字符数据,也可以往往写字己的数据,你说老师万一这个地方没有呢,他为啥正好有这个方法,对,还是那一句话,他一定是设计好的,你验什么serve,你既能往外写字符数据,也能往往写字节的数据,他如果没有这个方法,只能写字符数据,那这个S肯定大家也不会用它,为什么我只能写,我只能写字符数语,字节数语我写不了,那那它的局限性也太大了,所以那我们这个地方写了,那这个地方同样道理,那我这个什么要定义一个什么,对out put stream out stream去接收它这行了,然后呢,大看我现在就拿到这个流了,拿到这个流怎么办呢。
29:37
对,这个流我们说通过response拿到的,通过response response将来要回到浏览器。要理亏到浏览器,那么现在我们这个什么,现在我们运行的是在我们程序里边,Java代码里边,我想通过这个流,这个流现在什么就通过Java代码去连到浏览器了,是不是这个意思,就就是这个意思,通过这个al这个流,然后呢,在我的Java代码和这个浏览器之间就建立了这一个什么流,这是一个管道,那么将来通过这个管道就可以什么把我Excel文件输出过去了,那输出过去怎么输出呢?
30:14
那输出过直接用output stream直接往外right往外写就行了,往外写的时候数据从哪来呢?是不是从那个Excel文件里边来了,Excel文件在哪呢?对,是不是在文件里边呢?文件是不是在磁盘上面呢?在磁盘上面呢?那在磁盘上面你的Java程序现在运行到内存里边。那这他这个文件在磁盘上面的,你要想把这个文件里边数据通过这个什么程序写到浏览器,你在干什么?对,先把磁盘上的数据读到程序里边,然后呢,再通过程序往外写到浏览器,是不是这个意思,所以我们首先去这个文件,那怎么通过程序去读这个文件呢?
31:01
对,通过输入流是不是这样的,读文件通过什么输入流,文件输入流是不是这个意思,所以我首先去读读,我要我得溜一个fire input的令去连它,连它之后通过这个输入流就可以一个一个一个字节,一个字节或者多个字节,一一个缓冲区,一个缓冲序,读到这么程序里边,读完之后,然后就会往往往外写了,通过这个输出里往,所以这个地方我就这样了,首先去读取知读取,然后呢磁盘上的Excel文件,然后呢先把它读到内存里边,然后呢把文件读到内存的文件输出到浏览器,浏览器然后呢,读的时候肯定用这种流叫input STEM啊input STEM,然后写的时候肯定用output STEM。Output,让他。好,下边auto put stream已经有了,现在我只需要创建一个input stream了,要读一个文件,那用个fire input stream,这里边有个参数,这个参数表示什么意思?对,读哪一个文件,把这个文件路径写到这,那我肯定读服务器上这个文件了,然呢把这个文件路径写到这,然后呢,把这文件名写到这,我要读这个磁盘上的这个文件去,然后呢,定个变量叫input和对应用啊is这样就行了,这样的话大家我就建立了一个管道,从过程序读磁盘上的建立一个管道了,建立管道怎么了?就通过这个流把这里边数据读这读进来了,怎么读它里边是不是有read的方法。
32:47
知道V的话,你调它一个一个字节一个字节读,但是我一个字节一个字节效率是不是太低了,对可以建立一个缓冲区,一个缓冲区一个缓冲区的读,知道吧,这是我们这样,然后呢,这个地方我们来这个地方来,然后呢,那或建立一个缓冲区,这个缓冲区其实就是不是一个一个字节的一个数组啊,多个字节多个字节的,然后呢,这个时定个变量,这个数组定义多大呢。
33:12
大家看到你的文件大小,文件大一次是不是多读几个字节,文件小少读几个,那我们这个地方假如说来一个256吧,简单这么写了,那么将来读的时候,每次读这么一个缓冲区。读完之后,那么读每次什么,从这个什么文件里边读这么多的字节,读到哪了,就读到这个缓冲区里边,读完之后干什么。读到缓冲序的时候,是不是要要通过这个流把这个缓冲序里边数据往外写了,怎么写啊,里边有个方法叫什么right right往外写,把谁把这个缓冲里边数去写,写的时候大我就往每次读,每次往外写,是不是这样的,读一个缓冲序,写一个缓冲序,那到底有几个缓冲序呢?
34:03
这个文件看你去多大了,所以我也不知道能让这能读读读几个缓冲去,那怎么办呢?是不是可以写到一个循环里边,写到循环,那循环里边循环次数不确定,到底读几次我不确定,因我外边循环是我也不管它,我也不管它读几次,然后呢,就把这个地方,反正在这个方在这里边每次就读,对在这边每次用它,每次用它去读,去读一个反程语,读完之后返回值,它是不是一个返回值啊,反值什么类型的,In特类型,In特类型是表示什么?对表示每次读几个字节,这个缓程序有可能读不满,最后一次有可能读不满,是不是这样子,他读几个字节,这个地方返回一个读几个字节啊,那读到什么时候算读完,对,读到这个返回值是负一的时候就读完了,反过来换句话说,只要不等于负一,是不是一直读下去,一直得每次读,每次读一个缓冲区,然。
35:03
他们都执行这个循环题,把这个循环题写了吧。把把在循环体里边,把这个什么,通过这个输出流,把每次读这个缓冲区写,注意那写完之后,我们说这个缓冲有可能被读满,那从第这个缓冲器里边第几个元素往外写第零个,每次写几个元素,这一次读几个写几个,这样的话,那我们这个呢,就是一个循环嘛。然后呢,读完了也都写完了,把这个什么通过这个流输入流,把一个文件全读进来,然后呢,通过这个输入流全输入到浏览器了,这个地方大家能能理解这个意思吗。对,能理解,其实就是一个什么文件复制的一个过程。文件复制写过吗?写过怎么就怎怎么文件复制磁盘上的一个文件浏览器,然后呢,这是你的程序,以前你文件复制怎么读这个文件,每读几个字节,把它写到这个文件里边,是不是这样吗。
36:00
现在有什么不一样的地方什么?把这个文件换成浏览器了,不一样吗?道理不一样吗?道理是一样的,就是一个文件复制的过程,好这样的话呢,我们就可以了,可以完了之后呢,读完也响了,下边是不是该关的流关一下就行了,哪些关该关的流close,然后呢,这个是out.out别关啊out别out,为啥不关?奥,是你从那个派进来,对淘派乐进来了是吧,这样我们在加va在Java时候有个原则是吗?就这关闭资源的时候,对关闭资源对关闭资源的时候有个原则,这些资源谁开启的谁关闭。什么谁开启的,谁溜的,这个对象谁关,不是你溜的,你别关,那我们说大哥这个音符的组人母是不是我们程序员自己溜的,那你自己用完之后关了它就行了,这个out不谁谁溜的。
37:01
是程序员丢的吗?不是谁new的,对,瑞旺斯new的,瑞旺是谁new的,汤姆开new的,所以这个对象是淘开的no to门开的noole,你就别关,让to门开去关去知道吧,那你说老师我用完之后我不关的话,他门开头会关吗?To门开的一定会关,因为这是所有这程序员的原则,它开启了,用完之后他一定关,那就说我在这儿给他关了,不就省了他关了吗?对关对,关键是他创建这个对象,他是让你用的,你用完之后你还给他了,万一他创建这个对象不是仅仅给你用的呢,他你用完之后他还想再用一下呢,你在这给关了,他是不是就报错了。对,你给他关了,你用完了,他还想干一些别的事儿呢,那你在这儿你用完,你给他关了,你不管别的了,那他万一他还想再用一下呢。所以你给他关了,他再用他用不了了,所以他就报错了,他一报错抛不开的,一报错就严重了,你的程序就重要就完了,所以你的程序就错了,所以说啊,这个地方你别给他关,那因为我要不给他关,我要写到这个write里边,这缓存区里边数据没写到,还有的数据还在缓存器里边没写到,浏览器怎么你把你的数据刷走,Flash一样,你的数据就全走了。
38:25
至于关闭它自己会关,知道吧,好,这是我们说的这个程序我们就行了,这样的话咱我们这个后台就行了,那就这个代码。就是代码,这这个文件下载的这么个代码就行了,基本上这个代码都是大家以前学过的代码,就是换了一种写法,这是往外整,但是这个你要写这个代码还不行,还得有一个地方得设备,如果这如果这么写的话不行。哪个地方得设置一下啊,这个为什么不行,我先给大家说一下,为啥不行,为什么不行呢,是这。
39:02
你现在我们说从后台不管是自己返回数据也好,借助spring m Mac ctrl方法返回数据也好,浏览器拿到这个数据之后,默认的处理方式都是直接在显示窗口当中打开,这这是我们这这是我们说的这然后呢,浏览器接收到响应信息之后,信息之后不管是谁返回的,浏览器接收响应之后,默认情况下,默认情况下都是直接打开,直接在就显示窗口中,窗口中,然后呢打开直接在显示窗口中,然后呢,直接显示打开这个显示这个响应信息。它也就是说那个你返回这个什么,不管返回网页,还是接算字状还是还是Excel文件,它默认都是什么,直接在浏览器状给你打开,直接打开,那你说打开,万一他我返回网页,它能给我打开,我返问Excel文件它能打开吗?对他打不开,他打不开它也会自动掉你的时候。
40:14
电脑上的相应的软件,像office软件,如果你装了它也会给你打开,知道吗?而且有的浏览器现在做的都比较智能,它上面都内置了简版的office,在浏览器上面,甚至有的都能直接给你打开,总之他就直接打开,那即使打不开懂,即使他打不开啊,即使。即使打不开也会调用电脑上的吧,也会调用你电脑应用程序,就是说你这些office软件等等这些程序,然后呢,来打开来打开知道吧,那你说我软件,我这个电脑上压根就没装这种软件怎么。这个时候只有实在打不开了,只有实在打不开打不开。
41:01
实在是么?只有实在打不开才会,什么才会让呢?激活对才会激活文件小的窗口,窗口,然后让你去弹出来那个另存位,让你保存去保存怎么保存完了你再找别的软件去打开,就这个意思,这是浏览器的默认行为,但是我们要做文件下载,他要直接给我打开了,是不是他就下载不了了,所以这个这就不符合我们的需求,所以我们要做的是什么了。我们要做的事儿就是他不管返回什么信息,我只要想让他下载,他能打开,我也不让他打开,就直接激活文件下的窗务就行了,所以我们就可以这么来做了,怎么来做,你做个设置,别打破他这种默认行为是吧,我们可以什么可以可以设置响应投入信息,设置的响应投入信息,然后呢,使浏览器啊,使浏览器接收到响应信息信息之后,直接激活文件下载窗口,下载窗口,这样即使能打开也不打开,也不打开,知道吧。
42:23
那如何在设置,就这个设置设置响应图信息咋设置。Head响应信息有很多,设置哪个响应信息,这个叫content杠是么?叫什么dispo,这个不知道大家设置过没有?对,它就是设置浏览器接收到响应信息的时候,一个打开的方式啊,打开方式你要如果不设置,它默认直接的浏览器上面给你打开懂吗?那我就想让他下载怎么把它的值设置成这个,哪一个叫这个叫呃touchch门,呃它是告诉浏览器以呃它身边的形式来打开响应信息,呃它身份的什么意思。
43:08
翻译成中文叫什么叫附件是吗?附件附件附件的形式是什么?怎么怎么打开,那附件肯定就下载了是吗?就下载了知道吧,对后边还什么分号隔开,还有一个它还有个附加参数,这个附加参数你猜猜是什么意思?他给你激活那个文件下载窗口,文件下载窗口上面是不是默认填一个文件名啊,这个地方那个文件名你可以自己设置,叫啥都行,你比如说这个叫my student啊my student list.xls这样就行了,这样它就能它就可以了,将来你返回这个Excel文件之后,它能打开也不给你打开了,它就直接激活文件夹的入,并且上面有个默认的文件名就要好。好,有的时候什么还后边还得加一个什么加一个叫时间戳之类的,我们以后我们后边做CRM项目再给他加。
44:05
好,这样的话我们就可以了,可以完了之后呢,这个后台也响了,前台后台都响了,下边可以测一测了,启动服务测一测。然后呢,诶这个地方啊,找到我们这个启动服务来测一测。
我来说两句