目录
实现web开发中的文件上传功能,需要完成如下二步操作:
- 在web页面中添加上传输入项
- 在servlet中读取上传文件的数据,并保存到本地硬盘中
如何在web页面中添加上传输入项
标签用于在web页面中添加上传输入项,设置文件上传输入项的时需要注意:
必须要设置 输入项的 属性,否则浏览器将不会发送上传文件的数据。这就是之前发现的那个,如果一个标签没有 属性,是不会被提交的 。
必须把 的 属性设置 , 设置该值后,浏览器在上传文件时,把文件数据附带在 请求消息体 中,并使用 协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理 。
:这种表单提交,和以前的表单提交不一样,比如以前获取用户名,直接获取提交参数,就好了;使用了 协议以后,提交的数据格式将不再和以前一样,格式如下所示,因此,要获取其中的额数据,我们需要去使用特定的解析 ;
如何在 中读取文件上传数据,并保存到本地硬盘中?
- 对象提供一个 方法,通过这个方法可以获取客户端提交过来的数据。
- 但是由于用户可能会同时上传多个文件,在 端编程直接读取上传的数据,并解析出相应文件的数据是一件非常麻烦的工作。
- 为了方便处理用户上传数据, 开源组织提供了一个用来处理表单上传文件的一个开源组件(),该组件性能优异,并且 API 使用简洁 ;
使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的jar包:
乱码问题
文件名乱码问题
因为是老外写的,里面的内置的编码是,因此,在读取中文的时候,会出现乱码;
即使我们设置了的码表,也是无济于事的,对此,我们需要设置下解析器的码表 ;
普通字段乱码问题
这里由于表单类型是 ,即使我们设置了的编码,也是无济于事的,因为,问题出在, 方法上,它内部使用了。
要想改变它,用 的重载方法 ;
验证表单类型
- 在开始操作之前,先判断下表单类型,
;
返回 表示是上传表单 ;用于检测是否有人搞破坏!
- 在开始操作之前,先判断下表单类型,
文件大小、缓冲区问题
上传文件特别大情况,设置 和 ,临时文件需要自己设置自动删除 ;
;
设置内存缓存区大小,默认为 。当上传文件大于缓冲区大小的时候, 组件将使用临时文件缓存上传文件 ;
也就是说,当文件大小缓冲区的时候,使用缓冲区保存文件;如果临时文件缓冲区大小,则不使用缓冲区,而是先将文件写到临时文件里面保存 ;
也就是说,当文件缓冲区大小的时候,组件的作为一个中转站,先将文件写到缓冲区中,再从缓冲区写到服务器上 ;
如果文件大小缓冲区大小,则不再使用缓冲区作为中转站,而是使用作为中转,先将客户端的文件写到组件一个临时文件中,再从临时文件中写到服务器上 ;
备注:为什么需要中转?
原因很简单,中转说白了,就是一个缓冲区,我们将文件从文本上传到服务器,如果不使用缓冲区,直接从本地到服务器,每次磁头读取一次,然后送到服务器,然后磁头再次读取,循环往复;而每次磁头读取硬盘都是一个耗时的工作,我们应该减少磁头读取硬盘次数,或者说磁头读取一次硬盘,尽量的多读取数据,从而减少读取的次数,这样我们就需要,一个中转,让磁头一次读取更多的数据,然后保存到缓冲中;
如果没有中转当缓冲,那么一次磁头读取一个字节以后,就必须停止,待数据送达服务器端,才可以再次读取;这显然是不合理的,因此,我们需要缓冲区!
设置临时文件位置
使用 ,指定临时文件位置,参数接受一个文件路径,这里我们是在JEE中使用File,因此,需要得到文件的绝对路径,而不是相对路径;
使用 获取文件真实路径
指定临时文件目录,默认值是
临时文件需要我们删除掉,使用方法 ;
注意删除方法,要放在关闭流之后,否则还有流与文件关联,是删不掉的 ,确保被删掉,还需要放在里面;
对于保存上传文件,文件的保存目录,是绝对不能被外界访问到的;否则上传一段文本,然后访问这个文件,就会被执行!
这个目录的地址,需要好好写,不要在获得真实路径的字符串最后加上 ,路径和名字,中间用 路径分隔符 拼接,使用 来适应不同的系统 ;
其中,在上传文件的时候,项目中的文件夹下,是没有文件产生的,产生的文件在文件下 ;
文件的保存路径,我们必须放在文件夹下面,还有一个问题需要解决,windows操作系统,每个文件夹下面的直接文件数量超过的时候,打开该文件,就会卡顿,文件夹中文件夹中的数量,不算在直接文件数量中;
因此,我们需要设计出一个算法,来分配上传的文件;这里,我们根据文件名的哈希码来分配文件位置,哈希码是一个int值,一共32位,每4位为一个层次,生成文件夹,最多可以生成8层,可以保存上兆的文件了。;
:
在处理文件的时候,先获取文件的后缀名,做个判断,看是否在我们允许的文件类型之中 ;
如果文件没有上传,则服务器端获取 的时候是 ;
利用 生成随机ID ,再加上原本文件的名字,来防止文件名冲突的问题;
中利用代码,动态的添加、删除 ;
JS代码:
为解析器注册一个监听器,解析器里面有方法,当有数据被解析的时候,会被调用 ;
根据这个方法的参数,可以获取当前上传文件的进度 ;
超链接中有中文的时候,需要URL编码 ;
在JSP 标签中,我们使用 标签,来完成URL编码 ;
设置编码,对get方法提交的数据无效 ;
- 递归列出服务器的所有文件,数据量大的情况下,注意分页 ;
- 在中显示文件的时候,注意URL编码;
- 点击下载的时候,将文件的带过去;
- 在中,根据获取,要下载的文件对象,这个文件对象中封装该文件的信息;
- 检查判断文件是否存在;
- 文件存在,则进行文件名的编码,这里注意 和 其他浏览器的不同点;
对文件名中的空格,进行特殊处理;