一、组织结构
创建File_upload_download工程,导入jar,在建立其他文件。
二、文件上传所需的jar
//文件上传需要依赖的jar
commons-fileupload-1.3.1.jar
commons-io-2.2.jar
//el表达式需要的jar
jstl.jar
standard.jar
三、上传页面部署
- 单文件
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传页面</title>
</head>
<body>
<h1>上传文件信息</h1>
<hr>
<form method="post" action="${pageContext.request.contextPath }/upload.action" enctype="multipart/form-data">
文件概述<input type="text" name="message" ><br>
<input type="file" name="uploadfile"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
- 多文件
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>多文件上传页面</title>
</head>
<body>
<h1>上传文件信息</h1>
<hr>
<form method="post" action="${pageContext.request.contextPath }/upload.action"
enctype="multipart/form-data">
<div id="showUpload"></div>
<input type="button" value="添加文件" id="fileUpload" onclick="addFileItem()"><br>
<input type="submit" value="上传">
</form>
</body>
<script type="text/javascript">
function addFileItem() {
document.getElementById("showUpload").innerHTML += "<div><input type='file' name='uploadfile'> <input type='button' id='delete' value='删除' onclick='delItem(this)'></div>";
}
function delItem(button){
var parentDiv=button.parentNode;
parentDiv.parentNode.removeChild(parentDiv);
}
</script>
</html>
四、上传逻辑部分
@WebServlet("/upload.action")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 解决文件项中文乱码
req.setCharacterEncoding("utf-8");
// 1:创建文件上传的工厂对象
DiskFileItemFactory factory = new DiskFileItemFactory();
//缓存文件大小
factory.setSizeThreshold(10*1024*1024);
//缓存文件目录
factory.setRepository(new File("WEB-INF/tmp/"));
// 2:转化成ServletFileUpload对象
ServletFileUpload upload = new ServletFileUpload(factory);
final long strat = System.currentTimeMillis();
// 上传进度监听
upload.setProgressListener(new ProgressListener() {
/**
* pBytesRead 已上传 pContentLength 总大小 pItems 当前元素是表单第几个元素
*/
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
// TODO Auto-generated method stub
long current = System.currentTimeMillis();
// 使用时间
long use = (current - strat);
// 上传速度
long v = pBytesRead/8/ use;
// 剩余大小
long other = (pContentLength - pBytesRead)/8;
// 剩余时间
long t = other / v;
System.out.println("使用时间:" + use+"ms");
System.out.println("上传速度:" + v+"b/ms");
System.out.println("剩余大小:" + other+"b");
System.out.println("剩余时间:" + t+"ms");
}
});
// 解析
try {
// 设置单个文件大小 10M之内
upload.setFileSizeMax(10 * 1024 * 1024);
// 设置总文件大小 50M之内
upload.setSizeMax(50 * 1024 * 1024);
//3:遍历文件上传list集合,得到文件上传的全部内容
List<FileItem> list = upload.parseRequest(req);
for (FileItem file : list) {
// 普通项
if (file.isFormField()) {
// 上传文件普通项name属性
String fieldName = file.getFieldName();
// 上传普通项文本框内容,并解决中文乱码问题
String string = file.getString("utf-8");
System.out.println("普通项:" + fieldName + ":" + string);
}
// 文件项
else {
// 文件项名字
String name = file.getName();
if (name.lastIndexOf("\\") > 0) {
name = name.substring(name.lastIndexOf("\\") + 1);
}
// 文件项内容输入流
InputStream is = file.getInputStream();
// 上传路径WEB-INF,提高安全性
String path = getServletContext().getRealPath("WEB-INF/uploadFile/");
// 确保文件唯一,需要措施知道文件确切信息,提供下载
// 文件存放不同目录
String realPath = CreateFileUtil.showFile(path);
System.out.println("文件项路径:" + realPath);
FileOutputStream os = new FileOutputStream(new File(realPath, name));
IOUtils.copy(is, os);
//删除临时文件
file.delete();
is.close();
os.close();
}
}
} catch (FileUploadException e) {
// 捕捉单个文件大小异常
if (e instanceof FileSizeLimitExceededException) {
// 在request中保存错误信息
req.setAttribute("msg1", "上传失败!上传的文件超出了10MB!");
// 转发到index.jsp页面中!在index.jsp页面中需要使用${msg1}来显示错误信息
req.getRequestDispatcher("/index.jsp").forward(req, resp);
System.out.println("文件大小超过10M,请压缩后再上传!");
}
// 捕捉多个文件大小异常
if (e instanceof SizeLimitExceededException) {
// 在request中保存错误信息
req.setAttribute("msg2", "上传失败!上传的文件超出了50MB!");
// 转发到index.jsp页面中!在index.jsp页面中需要使用${msg2}来显示错误信息
req.getRequestDispatcher("/index.html").forward(req, resp);
System.out.println("文件总大小超过50M,请压缩后再上传!");
}
System.out.println("其他异常....");
}
}
}
5、文件目录生成工具函数
/**
* 生成上传文件存放不同目录
* @author qishui
*
*/
public class CreateFileUtil {
public static String showFile(String path) {
int hashCode = UUID.randomUUID().toString().hashCode();
String strPath = "";
while (hashCode > 0) {
strPath = strPath + ((hashCode) & 0xf) + "\\";
hashCode = hashCode >>> 4;
}
strPath = path + "\\" + strPath;
//若没有指定绝对路径,那么就会在此工程下创建目录
new File(strPath).mkdirs();
return strPath;
}
}