一、Servlet实现文件上传,需要添加第三方提供的jar包
下载地址:
1) commons-fileupload-1.2.2-bin.zip : 点击打开链接
2) commons-io-2.3-bin.zip : 点击打开链接
二:文件上传需要注意的问题:
0.文件上传的表单提交方式必须是POST方式,编码类型:enctype="multipart/form-data",默认是 application/x-www-form-urlencoded。比如:<form action="FileUpLoad"enctype="multipart/form-data"method="post">
1.上传文件的中文乱码
1.1 解决文件的乱码
ServletFileUpload.setHeaderEncoding("UTF-8")
1.2 解决普通输入项的乱码(注意,表单类型为multipart/form-data的时候,设置request的编码是无效的)
FileItem.setString("UTF-8"); //解决乱码
2.在处理表单之前,要记得调用:
ServletFileUpload.isMultipartContent方法判断提交表单的类型,如果该方法返回true,则按上传方式处理,否则按照传统方式处理表单即可。
3.设置解析器缓冲区的大小,以及临时文件的删除
设置解析器缓冲区的大小 DiskFileItemFactory.setSizeThreshold(1024*1024);
临时文件的删除:在程序中处理完上传文件后,一定要记得调用item.delete()方法,以删除临时文件
4.在做上传系统时,千万要注意上传文件的保存目录,这个上传文件的保存目录绝对不能让外界直接访问到。
5.限制上传文件的类型
在处理上传文件时,判断上传文件的后缀名是不是允许的
6.限制上传文件的大小
调用解析器的ServletFileUpload.setFileSizeMax(1024*1024*5);就可以限制上传文件的大小,如果上传文件超出限制,则解析器会抛FileUploadBase.FileSizeLimitExceededException异常,程序员通过是否抓到这个异常,进而就可以给用户友好提示。
7.如何判断空的上传输入项
String filename = item.getName().substring(item.getName().lastIndexOf("\\")+1); //""
if(filename==null || filename.trim().equals("")){
continue;
}
8、为避免上传文件的覆盖,程序在保存上传文件时,要为每一个文件生成一个唯一的文件名
public String generateFileName(String filename){
//83434-83u483-934934
return UUID.randomUUID().toString() + "_" + filename;
}
9、为避免在一个文件夹下面保存超过1000个文件,影响文件访问性能,程序应该把上传文件打散后存储。(也可以按时间)
public String generateSavePath(String path,String filename){
int hashcode = filename.hashCode(); //121221,采用的是哈希值进行打散
int dir1 = hashcode&15;
int dir2 = (hashcode>>4)&0xf;
String savepath = path + File.separator + dir1 + File.separator + dir2;
File file = new File(savepath);
if(!file.exists()){
file.mkdirs();
}
return savepath;
}
10、监听上传进度(进度条)
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("当前已解析:" + pBytesRead);
}
});
11、在web页面中添加动态上传输入项
三、举例:
1.fileupload.jsp
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
- %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <body>
- <!-- enctype 默认是 application/x-www-form-urlencoded -->
- <form action="FileUpLoad" enctype="multipart/form-data" method="post" >
- 用户名:<input type="text" name="usename"> <br/>
- 上传文件:<input type="file" name="file1"><br/>
- 上传文件: <input type="file" name="file2"><br/>
- <input type="submit" value="提交"/>
- </form>
- </body>
-
<script type="text/javascript">
function addfile(){
var files = document.getElementById("files");
var input = document.createElement("input");
input.type='file';
input.name='file';
var btn = document.createElement("input");
btn.type = 'button';
btn.value = '删除';
btn.onclick = function del(){
this.parentNode.parentNode.removeChild(this.parentNode);
}
var div = document.createElement("div");
div.appendChild(input);
div.appendChild(btn);
files.appendChild(div);
}
</script>
<body>
<form action="/day18/servlet/UploadServlet3" enctype="multipart/form-data" method="post">
<table>
<tr>
<td>上传用户</td> - <td><input type="text" name="username"></td>
</tr>
<tr>
<td>上传文件</td>
<td><input type="button" value="添加上传文件" οnclick="addfile()"></td>
</tr>
<tr>
<td></td>
<td><div id="files"></div></td>
</tr>
<tr>
<td></td>
<td> <input type="submit" value="上传"></td>
</tr>
</table>
</form>
</body>
</html>
2.实际处理文件上传的 FileUpLoad.java
<span style="font-family:KaiTi_GB2312;font-size:14px;">package cn.itcast.web.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
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.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List types = Arrays.asList("jpg", "gif", "avi", "txt");
try {
DiskFileItemFactory factory = new DiskFileItemFactory(); // 10k
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(new File(this.getServletContext()
.getRealPath("/temp")));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(new ProgressListener() {
public void update(long pBytesRead, long pContentLength,
int pItems) {
System.out.println("当前已解析:" + pBytesRead);
}
});
upload.setFileSizeMax(1024 * 1024 * 5);
if (!upload.isMultipartContent(request)) {
// 按照传统方式获取表单数据
request.getParameter("username");
return;
}
upload.setHeaderEncoding("UTF-8");
List<FileItem> list = upload.parseRequest(request);
for (FileItem item : list) {
if (item.isFormField()) {
// 为普通输入项
String inputName = item.getFieldName();
String inputValue = item.getString("UTF-8");
// inputValue = new
// String(inputValue.getBytes("iso8859-1"),"UTF-8");
System.out.println(inputName + "=" + inputValue);
} else {
String filename = item.getName().substring(
item.getName().lastIndexOf("\\") + 1); // ""
if (filename == null || filename.trim().equals("")) {
continue;
}
/*
* String ext =
* filename.substring(filename.lastIndexOf(".")+1);
* if(!types.contains(ext)){ request.setAttribute("message",
* "本系统不支持" + ext + "这种类型");
* request.getRequestDispatcher("/message.jsp"
* ).forward(request, response); return; }
*/
InputStream in = item.getInputStream();
int len = 0;
byte buffer[] = new byte[1024];
String saveFileName = generateFileName(filename);
String savepath = generateSavePath(this.getServletContext()
.getRealPath("/WEB-INF/upload"), saveFileName);
FileOutputStream out = new FileOutputStream(savepath
+ File.separator + saveFileName);
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
item.delete(); // 删除临时文件
}
}
} catch (FileUploadBase.FileSizeLimitExceededException e) {
request.setAttribute("message", "文件大小不能超过5m");
request.getRequestDispatcher("/message.jsp").forward(request,
response);
return;
} catch (Exception e) {
throw new RuntimeException(e);
}
request.setAttribute("message", "上传成功!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
//
public String generateSavePath(String path, String filename) {
int hashcode = filename.hashCode(); // 121221
int dir1 = hashcode & 15;
int dir2 = (hashcode >> 4) & 0xf;
String savepath = path + File.separator + dir1 + File.separator + dir2;
File file = new File(savepath);
if (!file.exists()) {
file.mkdirs();
}
return savepath;
}
public String generateFileName(String filename) {
return UUID.randomUUID().toString() + "_" + filename;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}</span>