首先 说明 本次只是简单的实现了 文件上传的进度和进度条显示 不支持 断点续传和取消
最近想动手 实现以下文件上传能够显示进度条 ,网上查了一下有的采用的是假的进度或者就是第三方插件。
无意中有重新看了一下apache commons-fileupload的官网 在用户指南最下边我们会发现有这个:
这不就是文件上传的进度监听嘛 ,apache都为我们做好了 为什么还要用什么第三方插件呢/
现在 就大概说一下实现思路吧:
- 自定义一个进度监听类实现ProgressListener接口 重写update方法 具体实现可以直接参考官网上面的
- 通过以读取的字节数跟文件总的字节数生成读取百分比 将该数字放在session中
- 创建一个servlet用来获取session中的百分比
- 在上传文件界面 在表单提交的时候 用ajax每隔100毫秒 访问 上文创建的servlet响应的百分比值 显示在界面
具体实现代码如下:
上传界面index.jsp的js:
- <script type="text/javascript">
- function callback(){
- $.ajax({
- type:"post",
- url:"FileUploadStatus",//响应文件上传进度的servlet
- success:function(msg){
- document.getElementById("span").innerHTML="已上传:"+msg;//显示读取百分比
- document.getElementById("table").width=msg;//通过表格宽度 实现进度条
- }
- })
- }
- function formSubmit(){
- window.setInterval("callback()", 100);//每隔100毫秒执行callback
- document.form.submit();
- }
<script type="text/javascript">
function callback(){
$.ajax({
type:"post",
url:"FileUploadStatus",//响应文件上传进度的servlet
success:function(msg){
document.getElementById("span").innerHTML="已上传:"+msg;//显示读取百分比
document.getElementById("table").width=msg;//通过表格宽度 实现进度条
}
})
}
function formSubmit(){
window.setInterval("callback()", 100);//每隔100毫秒执行callback
document.form.submit();
}
index.jsp 表单:
- <form action="FileUploadServlet" method="post" enctype="multipart/form-data" target="_parent" name="form">
- <input type="file" name="file" ><input type="button" onclick="formSubmit()" value="提交">
- </form>
- <span id="span"></span>
- <table width="300px;" border="0"><tr><td>
- <table id="table" height="20px;" style="background-color: gray;"><tr><td></td></tr></table>//用来实现进度条显示
- </td>
- </tr>
- </table>
<form action="FileUploadServlet" method="post" enctype="multipart/form-data" target="_parent" name="form">
<input type="file" name="file" ><input type="button" οnclick="formSubmit()" value="提交">
</form>
<span id="span"></span>
<table width="300px;" border="0"><tr><td>
<table id="table" height="20px;" style="background-color: gray;"><tr><td></td></tr></table>//用来实现进度条显示
</td>
</tr>
</table>
- 自定义进度监听类myProgressListener实现ProgressListener
自定义进度监听类myProgressListener实现ProgressListener
- public class myProgressListener implements ProgressListener {
- private double megaBytes = -1;
- private HttpSession session;
- public myProgressListener(HttpServletRequest request) {
- session=request.getSession();
- }
- public void update(long pBytesRead, long pContentLength, int pItems) {
- double mBytes = pBytesRead / 1000000;
- double total=pContentLength/1000000;
- if (megaBytes == mBytes) {
- return;
- }
- System.out.println("total====>"+total);
- System.out.println("mBytes====>"+mBytes);
- megaBytes = mBytes;
- System.out.println("megaBytes====>"+megaBytes);
- System.out.println("We are currently reading item " + pItems);
- if (pContentLength == -1) {
- System.out.println("So far, " + pBytesRead + " bytes have been read.");
- } else {
- System.out.println("So far, " + pBytesRead + " of " + pContentLength
- + " bytes have been read.");
- double read=(mBytes/total);
- NumberFormat nf=NumberFormat.getPercentInstance();
- System.out.println("read===>"+nf.format(read));//生成读取的百分比 并放入session中
- session.setAttribute("read", nf.format(read));
- }
- }
- }
public class myProgressListener implements ProgressListener {
private double megaBytes = -1;
private HttpSession session;
public myProgressListener(HttpServletRequest request) {
session=request.getSession();
}
public void update(long pBytesRead, long pContentLength, int pItems) {
double mBytes = pBytesRead / 1000000;
double total=pContentLength/1000000;
if (megaBytes == mBytes) {
return;
}
System.out.println("total====>"+total);
System.out.println("mBytes====>"+mBytes);
megaBytes = mBytes;
System.out.println("megaBytes====>"+megaBytes);
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength
+ " bytes have been read.");
double read=(mBytes/total);
NumberFormat nf=NumberFormat.getPercentInstance();
System.out.println("read===>"+nf.format(read));//生成读取的百分比 并放入session中
session.setAttribute("read", nf.format(read));
}
}
}
封装FileUpload 用来接收request中的表单域 和 file文件域
- public class FileUpload {
- private Map<String,String> params;
- private Map<String,FileItem> files;
- public FileUpload() {
- params=new HashMap<String, String>();
- files=new HashMap<String, FileItem>();
- }
- public void setMap(HttpServletRequest request){
- // Create a factory for disk-based file items
- FileItemFactory factory = new DiskFileItemFactory();
- // Create a new file upload handler
- ServletFileUpload upload = new ServletFileUpload(factory);
- upload.setHeaderEncoding("utf-8");
- upload.setProgressListener(new myProgressListener(request));//设置进度监听器
- // Parse the request
- try {
- List items = upload.parseRequest(request);
- Iterator iter = items.iterator();
- while (iter.hasNext()) {
- FileItem item = (FileItem) iter.next();
- if (item.isFormField()) {
- String name = item.getFieldName();
- String value = item.getString();
- params.put(name, value);
- }
- else{
- String name=item.getFieldName();
- files.put(name, item);
- }
- }
- } catch (FileUploadException e) {
- e.printStackTrace();
- }
- }
- public Map<String, String> getParams() {
- return params;
- }
- public Map<String, FileItem> getFiles() {
- return files;
- }
- //用来获取文件的名字
- public String getFileName(FileItem item){
- String fName=item.getName();
- System.out.println("fname=====>"+fName);
- int lastIndex=fName.lastIndexOf("\\");
- fName=fName.substring(lastIndex+1);
- System.out.println("new fname=====>"+fName);
- return fName;
- }
- }
public class FileUpload {
private Map<String,String> params;
private Map<String,FileItem> files;
public FileUpload() {
params=new HashMap<String, String>();
files=new HashMap<String, FileItem>();
}
public void setMap(HttpServletRequest request){
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8");
upload.setProgressListener(new myProgressListener(request));//设置进度监听器
// Parse the request
try {
List items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
params.put(name, value);
}
else{
String name=item.getFieldName();
files.put(name, item);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public Map<String, String> getParams() {
return params;
}
public Map<String, FileItem> getFiles() {
return files;
}
//用来获取文件的名字
public String getFileName(FileItem item){
String fName=item.getName();
System.out.println("fname=====>"+fName);
int lastIndex=fName.lastIndexOf("\\");
fName=fName.substring(lastIndex+1);
System.out.println("new fname=====>"+fName);
return fName;
}
}
实现文件上传的servlet
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=utf-8");
- PrintWriter out = response.getWriter();
- FileUpload fu=new FileUpload();
- fu.setMap(request);//解析request
- Map<String,FileItem> files=fu.getFiles();
- String fileName =fu.getFileName(files.get("file"));
- File file=new File(this.getServletContext().getRealPath("upload\\"+fileName));
- try {
- files.get("file").write(file);
- } catch (Exception e) {
- e.printStackTrace();
- }
- out.println("<script>alert('上传成功!');history.back();</script>");
- }
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
FileUpload fu=new FileUpload();
fu.setMap(request);//解析request
Map<String,FileItem> files=fu.getFiles();
String fileName =fu.getFileName(files.get("file"));
File file=new File(this.getServletContext().getRealPath("upload\\"+fileName));
try {
files.get("file").write(file);
} catch (Exception e) {
e.printStackTrace();
}
out.println("<script>alert('上传成功!');history.back();</script>");
}
实现用来响应上传进度的servlet FileUploadStatus
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=utf-8");
- PrintWriter out = response.getWriter();
- HttpSession session=request.getSession();
- String status=(String) session.getAttribute("read");//获取上传进度百分比
- System.out.println(status+"FileUploadStatus");
- out.println(status);//响应
- }
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session=request.getSession();
String status=(String) session.getAttribute("read");//获取上传进度百分比
System.out.println(status+"FileUploadStatus");
out.println(status);//响应
}
效果如下图:
测试 过程中 小文件 可能效果不明显 最好弄个大文件测试一下
实现方法、效果可能不是多完美 但好歹 也是亲自实现的 还是挺开心的额.....