文件上传下载原理
在TCP/IP中,最早出现的文件上传下载机制是FTP,它是将文件由服务器的标准机制。
但是在JSP编程中不能使用FTP方法来上传文件,这是由JSP运行机制决定的。
上传原理:
通过为表单元素设置method="post" enctype="multippart/form-data"属性,让表单提交的数据以二进制编码的
方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传
enctype属性:
applic ation/x-www-form-urlencoded:默认,只处理表单域里的value属性值,将表单域里的属性值处理成url编码方式。
multipart/form-data:表单以二进制流的方式来处理表单数据,会把文件域指定的内容也封装到请求参数里
text/plain:主要适用于通过表单发送邮件的方式
下载原理:
步骤1:HttpServletResponse.setContentType方法来设置Content-type头字段的值,为浏览器无法使用某种方式或激活某个程序来处理MIME类型,如"application/octet-stream"或"application/x-msddownload"
步骤2:通过HttpServletResponse..setHeader方法设置Content-Disposition头的值为"attachment;filename=文件名"
步骤3:读取下载文件,调用HttpServelResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件文件内容。
实现文件上传下载的方法有很多种:
JSP+Sevlet,SmartUpload,FileUpload,Struct2
此处详细说明FileUpload实现上传下载的方法。
上传:
/ 设置文件保存路径
String savePath = this.getServletContext().getRealPath(
"/WEB-INF/upload");
DiskFileItemFactory factory = new DiskFileItemFactory();// 磁盘对象
File file = new File(this.getServletContext().getRealPath(
"/WEB-INF/temp"));
// 如果文件夹不存在,则创建一个新的
if (!file.exists()) {
file.mkdirs();
}
factory.setSizeThreshold(1024 * 8); // 8k的缓冲区,文件大于8K则保存到临时目录
factory.setRepository(file);// 用临时文件保存解析出来的数据
ServletFileUpload upload = new ServletFileUpload(factory);// 声明解析的request对象
// 判断是普通表单,还是带文件上传的表单。文件上传的表单值不能按普通表单接收值那样直接获取
if (!ServletFileUpload.isMultipartContent(request)) {
return;
}
upload.setFileSizeMax(1024 * 1024 * 5);// 设置每个文件的大小不能超过10M
upload.setSizeMax(1024 * 1024 * 50);// 设置一共上传的文件大小不能超过50M
List<FileItem> list = upload.parseRequest(request);// 把每个提交的表单项打包成一个list
for (FileItem item : list) {
// 判断为普通的表单输入域还是文件输入域
if (item.isFormField()) {
return;
} else {
String filename = item.getName();
if (filename == null || filename.trim().equals("")) {
continue;
}
// 截取文件名
filename = filename
.substring(filename.lastIndexOf("\\") + 1);
InputStream in = item.getInputStream();
// 防止文件覆盖
String saveFilename = makeFileName(filename);
// 真正的存储路径
String realSavePath = makePath(saveFilename, savePath);
String allPath = realSavePath + "\\" + saveFilename;
attach.setAttachTitle(saveFilename);
attach.setAttachPath(allPath);
// 向数据库中插入数据
attachService.addAttach(attach, fareId);
request.setAttribute("fareId", fareId);
FileOutputStream out = new FileOutputStream(allPath);
byte buffer[] = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
item.delete();
}
1.??为什么要
factory.setRepository(new File(this.getServletContext().getRealPath("/WEB-INF/temp")));//设置临时文件路径
因为当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir 获取。如下代码:
System.getProperty("java.io.tmpdir");
Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。
Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为Java虚拟机默认可以使用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。
2.当前台input的type="file"时就会有默认的按钮“选择文件(未选择文件)”或者“浏览”界面,其界面样式根据不同的浏览器而定,点击按钮就会弹出文件上传的窗口。
下载:
弹框:response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(realname, "UTF-8"));
文件上传下载原理
在TCP/IP中,最早出现的文件上传下载机制是FTP,它是将文件由服务器的标准机制。
但是在JSP编程中不能使用FTP方法来上传文件,这是由JSP运行机制决定的。
上传原理:
通过为表单元素设置method="post" enctype="multippart/form-data"属性,让表单提交的数据以二进制编码的
方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传
enctype属性:
applic ation/x-www-form-urlencoded:默认,只处理表单域里的value属性值,将表单域里的属性值处理成url编码方式。
multipart/form-data:表单以二进制流的方式来处理表单数据,会把文件域指定的内容也封装到请求参数里
text/plain:主要适用于通过表单发送邮件的方式
下载原理:
步骤1:HttpServletResponse.setContentType方法来设置Content-type头字段的值,为浏览器无法使用某种方式或激活某个程序来处理MIME类型,如"application/octet-stream"或"application/x-msddownload"步骤2:通过HttpServletResponse..setHeader方法设置Content-Disposition头的值为"attachment;filename=文件名"
步骤3:读取下载文件,调用HttpServelResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件文件内容。
实现文件上传下载的方法有很多种:
JSP+Sevlet,SmartUpload,FileUpload,Struct2
此处详细说明FileUpload实现上传下载的方法。
上传:
/ 设置文件保存路径
String savePath = this.getServletContext().getRealPath(
"/WEB-INF/upload");
DiskFileItemFactory factory = new DiskFileItemFactory();// 磁盘对象
File file = new File(this.getServletContext().getRealPath(
"/WEB-INF/temp"));
// 如果文件夹不存在,则创建一个新的
if (!file.exists()) {
file.mkdirs();
}
factory.setSizeThreshold(1024 * 8); // 8k的缓冲区,文件大于8K则保存到临时目录
factory.setRepository(file);// 用临时文件保存解析出来的数据
ServletFileUpload upload = new ServletFileUpload(factory);// 声明解析的request对象
// 判断是普通表单,还是带文件上传的表单。文件上传的表单值不能按普通表单接收值那样直接获取
if (!ServletFileUpload.isMultipartContent(request)) {
return;
}
upload.setFileSizeMax(1024 * 1024 * 5);// 设置每个文件的大小不能超过10M
upload.setSizeMax(1024 * 1024 * 50);// 设置一共上传的文件大小不能超过50M
List<FileItem> list = upload.parseRequest(request);// 把每个提交的表单项打包成一个list
for (FileItem item : list) {
// 判断为普通的表单输入域还是文件输入域
if (item.isFormField()) {
return;
} else {
String filename = item.getName();
if (filename == null || filename.trim().equals("")) {
continue;
}
// 截取文件名
filename = filename
.substring(filename.lastIndexOf("\\") + 1);
InputStream in = item.getInputStream();
// 防止文件覆盖
String saveFilename = makeFileName(filename);
// 真正的存储路径
String realSavePath = makePath(saveFilename, savePath);
String allPath = realSavePath + "\\" + saveFilename;
attach.setAttachTitle(saveFilename);
attach.setAttachPath(allPath);
// 向数据库中插入数据
attachService.addAttach(attach, fareId);
request.setAttribute("fareId", fareId);
FileOutputStream out = new FileOutputStream(allPath);
byte buffer[] = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
item.delete();
}
1.??为什么要
factory.setRepository(new File(this.getServletContext().getRealPath("/WEB-INF/temp")));//设置临时文件路径
因为当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir 获取。如下代码:
System.getProperty("java.io.tmpdir");
Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。
Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为Java虚拟机默认可以使用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。
2.当前台input的type="file"时就会有默认的按钮“选择文件(未选择文件)”或者“浏览”界面,其界面样式根据不同的浏览器而定,点击按钮就会弹出文件上传的窗口。
下载:
弹框:response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(realname, "UTF-8"));