JavaWeb实现⽂件上传下载功能实例详解
在Web应⽤系统开发中,⽂件上传和下载功能是⾮常常⽤的功能,今天来讲⼀下JavaWeb中的⽂件上传和下载功能的实现。
⽂件上传概述
1、⽂件上传的作⽤
例如⽹络硬盘!就是⽤来上传下载⽂件的。
在智联招聘上填写⼀个完整的简历还需要上传照⽚呢。
2、⽂件上传对页⾯的要求
上传⽂件的要求⽐较多,需要记⼀下:
必须使⽤表单,⽽不能是超链接
表单的method必须是POST,⽽不能是GET
表单的enctype必须是multipart/form-data
在表单中添加file表单字段,即<input type=”file” name=”xxx”/>
<form action="${tPath }/FileUploadServlet"
method="post" enctype="multipart/form-data">
⽤户名:<input type="text" name="username"/><br/>
⽂件1:<input type="file" name="file1"/><br/>
⽂件2:<input type="file" name="file2"/><br/>
js截取某个字符之前的字符串<input type="submit" value="提交"/>
</form>
3、⽐对⽂件上传表单和普通⽂本表单的区别
dtd是什么贸易术语通过httpWatch查看“⽂件上传表单”和“普通⽂本表单”的区别。
⽂件上传表单的enctype=”multipart/form-data”,表⽰多部件表单数据;
普通⽂本表单可以不设置enctype属性:
当method=”post”时,enctype的默认值为application/x-www-form-urlencoded,表⽰使⽤url编码正⽂
当method=”get”时,enctype的默认值为null,没有正⽂,所以就不需要enctype了
对普通⽂本表单的测试:
<form action="${tPath }/FileUploadServlet" method="post">
⽤户名:<input type="text" name="username"/><br/>
⽂件1:<input type="file" name="file1"/><br/>
⽂件2:<input type="file" name="file2"/><br/>
<input type="submit" value="提交"/>
</form>
通过httpWatch测试,查看表单的请求数据正⽂,我们发现请求中只有⽂件名称,⽽没有⽂件内容。也就是说,当表单的enctype不是multipart/form-data时,请求中不包含⽂件内容,⽽只有⽂件的名称,这说明普通⽂本表单中input:file与input:text 没什么区别了。
对⽂件上传表单的测试:
<form action="${tPath }/FileUploadServlet"
method="post" enctype="multipart/form-data">
⽤户名:<input type="text" name="username"/><br/>
⽂件1:<input type="file" name="file1"/><br/>
⽂件2:<input type="file" name="file2"/><br/>
<input type="submit" value="提交"/>
</form>
通过httpWatch测试,查看表单的请求数据正⽂部分,发现正⽂部分是由多个部件组成,每个部件对应⼀个表单字段,每个部件都有⾃⼰的头信息。头信息下⾯是空⾏,空⾏下⾯是字段的正⽂部分。多个部件之间使⽤随机⽣成的分隔线隔开。
⽂本字段的头信息中只包含⼀条头信息,即Content-Disposition,这个头信息的值有两个部分,第⼀部分是固定的,即form-data,第⼆部分为字段的名称。在空⾏后⾯就是正⽂部分了,正⽂部分就是在⽂本框中填写的内容。
⽂件字段的头信息中包含两条头信息,Content-Disposition和Content-Type。Content-Disposition中多出⼀个filename,它指定的是上传的⽂件名称。⽽Content-Type指定的是上传⽂件的类型。⽂件字段的正⽂部分就是⽂件的内容。
接口类型都有哪些请注意,因为我们上传的⽂件都是普通⽂本⽂件,即txt⽂件,所以在httpWatch中是可以正常显⽰的,如果上传的是exe、mp3等⽂件,那么在httpWatch看到的就是乱码了
4、⽂件上传对Servlet的要求
当提交的表单是⽂件上传表单时,那么对Servlet也是有要求的。
⾸先我们要肯定⼀点,⽂件上传表单的数据也是被封装到request对象中的。
这时可以使⽤request的getInputStream()⽅法获取ServletInputStream对象,它是InputStream的⼦类,这个ServletInputStream对象对应整个表单的正⽂部分(从第⼀个分隔线开始,到最后),这说明我们需要的解析流中的数据。当然解析它是很⿇烦的⼀件事情,⽽Apache已经帮我们提供了解析它的⼯具:commons-fileupload
可以尝试把InputStream()这个流中的内容打印出来,再对⽐httpWatch中的请求数据
public void doPost(HttpServletRequest request, HttpServletResponse response)websocket和socket
throws ServletException, IOException {
InputStream in = InputStream();
String s = String(in);
System.out.println(s);
}
-----------------------------7ddd3370ab2
Content-Disposition: form-data; name="username"
hellojava下载过程
-----------------------------7ddd3370ab2
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
aaa
-----------------------------7ddd3370ab2
Content-Disposition: form-data; name="file2"; filename="b.txt"
Content-Type: text/plain
bbb
-----------------------------7ddd3370ab2--
commons-fileupload
为什么使⽤fileupload:
上传⽂件的要求⽐较多,需要记⼀下:
必须是POST表单;
表单的enctype必须是multipart/form-data;
在表单中添加file表单字段,即
Servlet的要求:
不能再使⽤Parameter()来获取表单数据
可以使⽤InputStream()得到所有的表单数据,⽽不是⼀个表单项的数据
这说明不使⽤fileupload,我们需要⾃⼰来对InputStream()的内容进⾏解析
1、fileupload概述
fileupload是由apache的commons组件提供的上传组件。它最主要的⼯作就是帮我们解析InputStream() fileupload组件需要的JAR包有:
commons-fileupload.jar,核⼼包
commons-io.jar,依赖包
2、fileupload简单应⽤
fileupload的核⼼类有:DiskFileItemFactory、ServletFileUpload、FileItem
使⽤fileupload组件的步骤如下:
//1.创建⼯⼚类DiskFileItemFactory对象
DiskFileItemFactory factory = new DiskFileItemFactory();
//2.使⽤⼯⼚创建解析器对象
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//3.使⽤解析器来解析request对象
List<FileItem> list = fileUpload.parseRequest(request);
DiskFileItemFactory 磁盘⽂件项⼯⼚类
public DiskFileItemFactory(int sizeThreshold, File repository) 构造⼯⼚时,指定内存缓冲区⼤⼩和临时⽂件存放位置public void setSizeThreshold(int sizeThreshold) 设置内存缓冲区⼤⼩,默认10K
public void setRepository(File repository) 设置临时⽂件存放位置,默认Property(“pdir”).
内存缓冲区:上传⽂件时,上传⽂件的内容优先保存在内存缓冲区中,当上传⽂件⼤⼩超过缓冲区⼤⼩,就会在服务器端产⽣临时⽂件
临时⽂件存放位置:保存超过了内存缓冲区⼤⼩上传⽂件⽽产⽣临时⽂件,产⽣临时⽂件可以通过 FileItem的delete()⽅法删除
FileItem 表⽰⽂件上传表单中每个数据部分
隆重介绍FileItem类,它才是我们最终要的结果。⼀个FileItem对象对应⼀个表单项(表单字段)。⼀个表单中存在⽂件字段
和普通字段,可以使⽤FileItem类的isFormField()⽅法来判断表单字段是否为普通字段,如果不是普通字段,那么就是⽂件字段了
注意事项:因为⽂件上传表单采⽤编码⽅式multipart/form-data 与传统url编码不同,所有getParameter ()⽅法不能使⽤setCharacterEncoding()⽆法解决输⼊项乱码问题
ServletFileUpload ⽂件上传核⼼类
3、简单上传⽰例
写⼀个简单的上传⽰例:
表单包含⼀个⽤户名字段,以及⼀个⽂件字段;
Servlet保存上传的⽂件到uploads⽬录,显⽰⽤户名,⽂件名,⽂件⼤⼩,⽂件类型。
第⼀步:
完成index.jsp,只需要⼀个表单。注意表单必须是post的,⽽且enctype必须是mulitpart/form-data的
怎么没有水印的视频素材<form action="${tPath }/FileUploadServlet"
method="post" enctype="multipart/form-data">
⽤户名:<input type="text" name="username"/><br/>
⽂件1:<input type="file" name="file1"/><br/>
<input type="submit" value="提交"/>
</form>
第⼆步:完成FileUploadServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 因为要使⽤response打印,所以设置其编码
response.setContentType("text/html;charset=utf-8");
// 创建⼯⼚
DiskFileItemFactory dfif = new DiskFileItemFactory();
// 使⽤⼯⼚创建解析器对象
ServletFileUpload fileUpload = new ServletFileUpload(dfif);
try {
/
/ 使⽤解析器对象解析request,得到FileItem列表
List<FileItem> list = fileUpload.parseRequest(request);
// 遍历所有表单项
for(FileItem fileItem : list) {
// 如果当前表单项为普通表单项
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论