文件上传是JaveWeb开发者经常遇到的一个功能,目前文件上传的技术也是五花八门,这其中Apache旗下的commons-fileupload组件是使用比较广泛的一个文件上传的开源组件,基于commons-fileupload实现文件上传操作简单,并且commons-fileupload还提供了文件获得文件上传进度的接口,基于此,开发者就可以在页面上实时动态的显示文件上传的进度,很大程度提高用户的体验。
页面上动态变化的进度条其实是一个具有背景色的div块,让这个div块的宽度随着文件上传的进度的多少而变化就是进度条。这其中要解决的问题是如何实时获得文件上传的进度,并且页面在文件没有上传结束前不能跳转。显然,此时要从服务器获得文件上传的进度必须使用异步请求的方式。服务器端可以将当前文件上传的进度放置在Session域中,前台间隔一段时间通过Ajax异步的方式从服务器端的Session中获得文件上传的进度,并更新div的宽度。
HTML代码
[HTML] 纯文本查看 复制代码
<body>
<!-- 进度条的DIV -->
<div id="div1" style="background-color: red;height: 20px;width: 0"></div>
<!-- 表单 -->
<form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data">
文件描述:<input type="text" name="desc"><br/>
文件:<input type="file" name="file"><br/>
<input type="submit" value="提交">
</form>
</body>
Javascript代码
[JavaScript] 纯文本查看 复制代码
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(function(){
$("#div1").css("width","0");
setInterval("showProgress()",10);
});
//显示文件上传的进度
function showProgress(){
$.get("${pageContext.request.contextPath}/ShowFileUploadProgress",function(data){
$("#div1").css("width",data);
})
}
</script>
Java代码
FileUploadServlet.java
[Java] 纯文本查看 复制代码
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.NumberFormat;
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.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import cn.itcast.utils.FileUtils;
/**
* 文件上传的Servlet
*/
@SuppressWarnings("all")
public class FileUploadServlet extends HttpServlet {
protected void doGet(final HttpServletRequest request, HttpServletResponse response) {
try {
//1.创建磁盘文件工厂对象
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//2.创建核心的解析类对象
ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
//3.设置监听文件上传进度的监听器,以便获得文件上传的进度
fileUpload.setProgressListener(new ProgressListener() {
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
double pRead = pBytesRead;
double pLength = pContentLength;
//获得数字格式化对象--百分比
NumberFormat format = NumberFormat.getPercentInstance();
//保留2位小数点
format.setMaximumFractionDigits(2);
//计算文件上传的进度
String percent = format.format(pRead/pLength);
System.out.println("已经上传的进度:"+percent);
//将文件上传的进度保存在Session域中
request.getSession().setAttribute("progress", percent);
}
});
//解决中文文件名上传的乱码的问题
fileUpload.setHeaderEncoding("UTF-8");
//4.解析请求,获得表单项的集合对象
List<FileItem> list = fileUpload.parseRequest(request);
//5.遍历表单项的集合
for (FileItem fileItem : list) {
//6.判断当前的表单项是否是文件项
if(fileItem.isFormField()){
//6.1.如果是普通文本项,获得参数的名称和值
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");
System.out.println(name+":"+value);
}else{
//6.2.如果是文件项,获取文件内容,使用流写入到服务器磁盘中
String fileName = fileItem.getName();
//文本保存的根目录
String baseDir = "C:\\Users\\fudingcheng\\Desktop\\file";
//获得文件保存子目录
String childDir = FileUtils.getDirNameByDate();
//判断子目录是否存在
File realDir = new File(baseDir+childDir);
if(!realDir.exists()){
realDir.mkdirs();
}
//将文件写到磁盘中
fileItem.write(new File(baseDir+childDir, fileName));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
ShowFileUploadProgress.java
[Java] 纯文本查看 复制代码
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 获取文件上传进度的Servlet
*/
@SuppressWarnings("serial")
public class ShowFileUploadProgress extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String percent = (String) request.getSession().getAttribute("progress");
response.getWriter().print(percent);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
FileUtils.java
[Java] 纯文本查看 复制代码
import java.util.Calendar;
/**
* 文件上传的工具类
*/
public class FileUtils {
/**
* 生成子目录的方法
*/
public static String getDirNameByDate(){
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH)+1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
return "/"+year+"/"+month+"/"+day;
}
}