一.文件上传
文件上传程序步骤
1.如何在web页面中添加上传输入项?
<input type=“file”>标签用于在web页面中添加文件上传输入项,设置文件上传输入项时须注意:
1)、
必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
2)、必须
把form的enctype属值设为multipart/form-data.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。
3)、表单的
提交方式要是post
2、服务器端 Servlet读取上传文件内容,保存到服务器端
常见问题:
1、表单控件没写name属性 ----- 上传文件数据不会提交
2、表单没有设置enctype enctype="application/x-www-form-urlencoded"
upload=C%3A%5CDocuments+and+Settings%5Cseawind%5C%E6%A1%8C%E9%9D%A2%5C2012%E5%B9%B42%E6%9C%8810%E6%97%A5%E7%8F%AD%5Cj2ee6_docs.chm
* 此时 请求数据包中 没有上传文件数据的
upload=C%3A%5CDocuments+and+Settings%5Cseawind%5C%E6%A1%8C%E9%9D%A2%5C2012%E5%B9%B42%E6%9C%8810%E6%97%A5%E7%8F%AD%5Cday20%5C%E7%AC%94%E8%AE%B0.txt
上传文件请求体格式
当使用enctype后 --- multipart/form-data
上传文件请求体 采用MIME消息格式 格式如下:
-----------------------------7dc2fd10407a8
Content-Disposition: form-data; name="username"
寮犱笁
-----------------------------7dc2fd10407a8
Content-Disposition: form-data; name="upload"; filename="C:\Documents and Settings\seawind\妗岄潰\info.txt"
Content-Type: text/plain
Iam ok!
today is sunny!
很好!
-----------------------------7dc2fd10407a8--
通过request.getInputStream 获得请求体中包含数据
解析上传文件数据
分析原理之后 需要使用开源技术来解决
1、JSP Smart-upload (产生于JSP盛行时代 Model1)
2、
commons-fileupload --- Apache commons项目中一个子项目
* upload jar 依赖 io包 ---- commoms-io
共需要导入两个jar包:
Commons-fileupload和commons-io
上传Servlet
创建文件项 工厂 FileItemFactory
此工厂类常用的方法:
1、SizeThreshold 设置内存缓冲区大小
上传文件时,文件首先是要保存在服务器内存缓冲区内
例如:缓冲区64m 上传200m文件 ---- 将内存缓冲区中数据,保存到硬盘上形成临时文件
2、Repository 设置临时目录
创建解析器 ServletFileUpload
1、 解析request数据
parseRequest ---- FileItem的List
什么是FileItem ----- MIME BodyPart
2、遍历List,寻找哪个是上传文件的FileItem
if(!fileItem.isFormField()){// 如果文件项不是一个简单表单域,他就是一个上传文件
}
文件上传API图解:
代码示例:
上传文件jsp示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>文件上传 form 表单</h1>
<form action="upload4" method="post" enctype="multipart/form-data">
用户名<input type="text" name="username" /><br/>
上传文件<input type="file" name="upload"/> <!-- 以post提交 数据在请求体中 -->
<input type="submit" />
</form>
</body>
</html>
上传文件servlet示例:
package cn.servlet;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 使用file upload 技术 进行文件上传
// 创建文件项工厂
DiskFileItemFactory factory = new DiskFileItemFactory(); // 目的:存放
// 创建ServletFileUpload
ServletFileUpload servletFileUpload = new ServletFileUpload(factory); // 解析器
// 解析
try {
// 获得文件项列表 -- 每一个文件项相当于 一个上传表单组件
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
System.out.println(fileItems.size());
// 查找哪个是上传文件项
for (FileItem fileItem : fileItems) {
// 判断fileItem是上传文件
if (!fileItem.isFormField()) {
// 上传文件
InputStream in = fileItem.getInputStream();
String fileName = fileItem.getName();
int index = fileName.lastIndexOf("\\");
if (index != -1) {
// 截取文件名
fileName = fileName.substring(index + 1);
}
FileOutputStream out = new FileOutputStream("c:\\"
+ fileName);
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
若干注意问题:
* 文件上传解析之前
需要先判断 该表单是否为文件上传表单 enctype="multipart/form-data"
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
* 对于
上传文件名中文乱码解决 setHeaderEncoding(java.lang.String encoding)
*
监听文件上传过程 setProgressListener(ProgressListener pListener) ------ 开发中结合AJax一起使用 进度条
* 如果form使用文件上传格式multipart ,此时不能再使用request.getParameter获得数据了
使用
getString