1. 文件上传下载概述
1.1. 什么是文件上传下载
所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程。例如目前网站需要上传头像、上传下载图片或网盘等功能都是利用文件上传下载功能实现的。
文件上传下载实际上是两步操作,第一是文件上传,就是将本地文件上传到服务器端,实现文件多用户之间的共享,第二是文件下载,就是将服务器端的文件下载到本地磁盘。
1.2. 文件上传下载实现原理
首先,需要知道文件是如何实现上传及下载的。文件上传及下载实现原理如下:
文件上传实现流程如下:
客户端浏览器通过文件浏览框,选择需要上传的文件内容(其中包括文件路径及文件内容)。
客户端浏览器通过点击上传按钮,将本地文件上传到服务器端。
服务器端通过程序接收本地文件内容,并将其保存在服务器端磁盘中。
文件下载实现流程如下:
客户端浏览器通过点击下载按钮,将服务器端保存的文件下载到本地磁盘。
服务器端通过程序将服务器端文件响应给客户端。
2. 文件上传实现
2.1. 文件上传客户端页面实现
在Web应用程序中实现文件上传功能,只需要在客户端页面中添加需要上传输入项,在服务器端Servlet中读取上传文件的数据,并保存在服务器端硬盘中即可。
客户端浏览器页面实现文件上传功能,具体代码如下:
My JSP 'upload.jsp' starting page文件描述:
需要注意的是:
标签必须指定name属性值,否则需要上传的文件数据是不会上传至服务器端。
完成文件上传功能的表单的请求类型必须是POST方式。
完成文件上传功能的表单的enctype属性值设置为“multipart/form-data”,该值的作用是将需要上传的文件数据添加到Http请求体中,并使用MIME协议对上传的文件进行描述。
2.2. commons-fileupload工具
完成客户端的文件上传功能之后,主要是在服务器端完成接收上传文件的数据内容。为了方便实现文件上传逻辑,可以使用第三方提供的文件上传包,具体如下:
jsp-smartupload.jar:使用JSP模型一时使用的,目前基本不再使用。
commons-fileupload.jar:由Apache基金会提供的,用来实现Java环境下的文件上传功能。
Servlet 3.0规范中提供对文件上传的支持。
commons-fileupload组件的官网地址:http://commons.apache.org/proper/commons-fileupload/。需要注意的是:在使用commons-fileupload组件时,需要依赖于commons-io包。commons-fileupload组件工作流程如下:
如何使用commons-fileupload组件实现文件上传功能,可以参考其官网的User Guide内容。
创建DiskFileItemFactory文件项工厂对象。
通过工厂对象获取文件上传请求核心解析类ServletFileUpload。
使用ServletFileUpload对应Request对象进行解析。
遍历每个fileItem,判断是否为上传项。
IOUtils.copy(inputStream,OutputStream)(将上传的数据拷贝到服务器的硬盘上的简单方法)
具体实现代码如下:
public class UploadServlet extendsHttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {
doPost(request, response);
}public void doPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//创建DiskFileItemFactory文件项工厂对象
DiskFileItemFactory factory = newDiskFileItemFactory();//通过工厂对象获取文件上传请求核心解析类ServletFileUpload
ServletFileUpload upload = newServletFileUpload(factory);try{//使用ServletFileUpload对应Request对象进行解析
List items =upload.parseRequest(request);//遍历每个fileItem
for(FileItem fileItem : items) {//判断fileItem是否是上传项
if(fileItem.isFormField()) {//返回true:表示不是上传项
String fieldName =fileItem.getFieldName();
String str= fileItem.getString("utf-8");
System.out.println(fieldName+" : "+str);
}else{//返回false:表示是上传项
String name =fileItem.getName();
InputStream in=fileItem.getInputStream();
String uploadPath= getServletContext().getRealPath("/upload");
OutputStream out= new FileOutputStream(newFile(uploadPath, name));intb;while ((b = in.read()) != -1) {
out.write(b);
}
out.close();
in.close();
}
}
}catch(FileUploadException e) {
e.printStackTrace();
}
}
}
2.3. 动态多文件上传表单
上述案例实现的是单文件上传,如果想实现多文件上传功能的话,服务器端的逻辑是一样的,也就是说,只需要在客户端页面实现多文件上传控件即可。动态实现多文件上传表单代码如下:
My JSP 'upload.jsp' starting pagefunctionadd(){//在div中添加上传输入项
document.getElementById("uploaddiv").innerHTML+= "
}functiondel(obj){//传入obj 就是你点击 按钮对象
vardiv=obj.parentNode;
div.parentNode.removeChild(div);
}