概念
和服务器通信
功能
解释说明:
mime:互联网中一种文件的类型,可以用servletContext对象来获取。
域对象:用来共享数据,里面有一些get,set,removeAttribute,只要搞清楚ServletContext对象的域的范围是什么
如何获取ServletContext对象
我们继承了httpServlet,我们就可以调用这个方法来获取
代码演示
是否相等:
上面概念说:ServletContext对象代表整个web应用,整个web应用就一份啊。所以是相等的。
结果:
浏览器访问:
结果输出:
两个对象地址值都一样,并且返回的是true:
!总结
所以不管通过哪种方式获取的servletContext对象,获取的都是那一个。
功能1——获取MIME类型
mime类型介绍
互联网通信过程中一种文件类型的标准,http协议也遵循mime类型的标准。
比如:
text/html:这个数据,纯文本的,并且里面定义的是html形式的。
image/jpeg:这个数据是图片,这个图片具体是jpg类型的。
在http协议的响应头里面的content-type设置文件的mime类型,设置之后告诉浏览器我给你发的数据或响应消息体是什么类型什么格式,你得用相应的解析引擎去解析他们。所以我们将来要去给客户端发送数据,得获取发送数据对应的mime类型。
获取:
接收一个文件的名称,返回一个文件的类型
是通过扩展名,文件的后缀名来获取的。
为什么这个方法可以获取到:
因为整个mime类型所有对应关系都在我们的服务器里面存储着,这个对象刚好又可以和我们的服务器来通信,所以他可以获取到:
查看服务器的web.xml:
查看html的:
jpg的:
代码演示
浏览器访问:
输出结果:
功能2——域对象
api方法
域范围
范围是最大的,服务器开启,这个对象被创建,张三往里面存数据,李四一会访问,也可以把这个数据拿到,是这个意思,共享所有的用户的数据的。
代码演示
demo3:
demo4:
浏览器先访问3,再换个浏览器访问4,相当于不同用户:
结果打印了预期的:
说明
一般我们用这个对象很谨慎,因为所有用户都能访问意味着所有用户都可以操作他,而且这个对象生命周期很长,服务器启动他会被创建,服务器关闭他才被销毁,所以这个对象驻留在内存里会保存很久的时间。我们需要很谨慎用它,因为里面的数据多了会造成内存的压力很大。
功能3——获取文件服务器路径
我们指的一切的路径都是服务器tomcat端的路径:
方法
代码演示
比如要读取一个配置文件,配置文件有三个地方可以放:
src下;web下;web-inf下
我们要读取配置文件,用file对象通过流加载,参数要通过servletcontext对象获取路径:
!!!说明,工作空间
我们启动服务器后:
这里每个项目都会对应一个配置,配置就是这个地方:
复制这个路径,去本地磁盘打开:
点进去:
打开:
真正定义的服务器路径:
就是我当前发布这个项目找的是工作空间里的out目录下面,他并没有给他拷贝到tomcat的webapps下面。
所以在这里我们可以找到这个目录:
就是这个目录里的东西被发布到服务器里并且访问它。
接着上面代码,现在我们来打印这个路径,我们来访问:
打印结果:
就是上面看的idea的project的out目录下的内容:
这个里面有个b.txt,我们就可以通过流加载他进内存。
访问c.txt(WEB-INF下的)
当前斜杠/代表:
那么我们找到web-inf的路径:
访问a.txt(src包下)
由于src下的所有东西将来会被放到web-inf的classes目录下
所以:
案例-文件下载
说明
我们页面直接超链接连接到图片:
使用绝对路径:
浏览器访问:
点击超链接不会有任何下载提示框,因为图片是可以被浏览器解析的,会直接展示这张图片在你的浏览器中。
但是如果是浏览器展示不出来的资源,他会弹框的:
比如视频,是无法被浏览器直接解析的,需要依赖于一些插件:
浏览器访问并点击:
这里google是高级的直接给下载了
用低级的ie:
会有打开或保存这些可选操作。
分析
我们的需求:
是要任何资源都要弹出这个下载提示框的。
解决:
设置了这么一个响应头之后,不管什么资源都不会默认在浏览器里面打开,会以附件的形式弹出。
现在超链接就不能指向图片资源了,应该指向servlet并且将要下载的资源用参数传递过去。
步骤
第一步解析:
指向servlet,将来所有的资源都会被这同一个servlet下载,就是说不管下载什么,都指向同一个servlet,那我们是不是应该区分一下,点击哪个超连接是下载图片的,点击哪个超链接是下载视频,我们应该传个参数:
我们在servlet里通过获取参数来加载不同的资源进内存,然后将数据写到客户端去。
第二步解析:
我们要干的事就是把这个文件用字节输入流读到内存里,再把内存里的数据写出到response的输出流里面。
加载文件进内存我们要找到这个文件的真实路径,就是还要使用servletcontext获取真实的路径。
代码实现
输出流不关但是输入流要关一下:
404的问题处理:
把路径单独复制出来访问一下,如果访问不了,那么这个路径一定有问题,字母大小写或者少些字符或者字母了。
单独访问:
仔细看发现是大小写和符号的缺少:
和正确的servlet的路径比对:
写改后(最上面的是正确写法)页面再访问:
成功:
中文文件名问题
情况演示
然后我们服务器的代码是不用改的,因为我们之前说过,tomcat8里get请求中文乱码问题自动被处理了。
然后我们页面访问:
点击后:
说:我们是遇不到这个情况的,因为当前视频演示浏览器ie版本太低了,和tomcat8兼容性不是很好。
使用火狐看下:
发现这里变成下划线了,不见了。
这就是中文文件名的一个问题,他将来在下载弹出的提示框里,中文数据是不能被正常展示的,而且这里还牵扯到不同的浏览器展示的样子不一样:
我们换360试下效果:
解决思路
这个问题将来会经常遇到因为将来文件下载操作用的是很多的。
这里获得的中文名称给他编个码:
代码实现
打开给的资料这个工具类:
工具类不需要记也不需要写:
传了一个agent浏览器版本信息,一个filename,他会把这个filename根据版本信息的不同给filename以不同的编码形式返回。
如下:ie的用URLEncoder;火狐用base64…
我们给他复制到项目里:
这种工具类网上有很多我们一找就找到了
然后我们只需要到我们的servlet里面去在设置这个文件名之前,解决中文文件名问题:
再重启用不同的浏览器发现:
弹出的框里面显示一样的正确的文件名: