文件上传---动作条
利用Apache commons fileupload上传文件,直接显示其完成的进度条。----示例代码源自《JAVA WEB王者归来》
1 首先要显示动作条要利用Ajax的异步请求,使得在没有完成时,不会刷新本页,而是局部的刷新。如果没有指定form的定向页面,默认是刷新本页,正常我们提交一个form刷新本页,在没有完成请求前是显示空白的网页,这里我们指定他刷新一个不显示的区域,就要用到form的属性target。
<iframe name=uploadiframe width=0 height=0></iframe> <form action="servlet/ProgressUploadServlet" method="post" enctype="multipart/form-data" target="uploadiframe" onsubmit="showStatus();"> <input type="file" name="file1" style="width:350px;"/><br/> <input type="file" name="file2" style="width:350px;"/><br/> <input type="file" name="file3" style="width:350px;"/><br/> <input type="submit" value="submit" id="btnSubmit"/> </form>
2 我们创建一个status的bean,用来保存一些状态信息,比如名字,读取的长度,读取的字节大小,时间等等。
public class UploadStatus { private long bytesRead; private long contentLength; private int items; private long startTime = System.currentTimeMillis(); public long getBytesRead() { return bytesRead; } public void setBytesRead(long bytesRead) { this.bytesRead = bytesRead; } public long getContentLength() { return contentLength; } public void setContentLength(long contentLength) { this.contentLength = contentLength; } public int getItems() { return items; } public void setItems(int items) { this.items = items; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } }
3 创建一个监听器实时的获取状态信息
public class UploadListener implements ProgressListener { private UploadStatus status; public UploadListener(UploadStatus status){ this.status = status; } public void update(long bytesRead,long contentLength,int items){ status.setBytesRead(bytesRead); status.setContentLength(contentLength); status.setItems(items); } }
4 form表单用pos方法提交后,在doPost里面获取状态信息,保存到session中。在本页面,在自动用get方法读取session中的信息,返回给网页,网页动态的进行数据的显示。
doPost
UploadStatus status = new UploadStatus(); UploadListener listener = new UploadListener(status); request.getSession(true).setAttribute("uploadStatus",status); ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setProgressListener(listener);
doGet
long startTime = status.getStartTime(); long currentTime = System.currentTimeMillis(); long time = (currentTime - startTime)/1000 + 1; double velocity = ((double)status.getBytesRead())/(double)time; double totalTime = status.getContentLength()/velocity; double timeLeft = totalTime - time; int percent = (int)(100*(double)status.getBytesRead()/(double)status.getContentLength()); double length = ((double)status.getBytesRead())/1024/1024; double totalLength = ((double)status.getContentLength())/1024/1024; String value = percent +"||" + length + "||" +totalLength+"||"+ velocity+"||"+time+"||"+totalTime+"||"+timeLeft+"||"+status.getItems(); response.getWriter().println(value);
js
<script type="text/javascript"> var finished = true; function $(obj){ return document.getElementById(obj); } function showStatus(){ finished = false; $('status').style.display = 'block'; $('progressBarItem').style.width = '1%'; $('btnSubmit').disabled = true; setTimeout("requestStatus()",1000); } function requestStatus(){ if(finished) return; var req = createRequest(); req.open("GET","servlet/ProgressUploadServlet"); req.onreadystatechange = function(){callback(req);} req.send(null); setTimeout("requestStatus()",1000); } function createRequest(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else{ try{ return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ return new ActiveXObject("Microsoft.XMLHTTP"); } } return null; } function callback(req){ if(req.readyState == 4){ if(req.status != 200){ debug("error! req.status:"+req.status+""); return ; } debug("status.jsp return value:"+req.responseText); var ss = req.responseText.split("||"); $('progressBarItem').style.width = ''+ss[0]+'%'; $('statusInfo').innerHTML = 'end of total:'+ss[0] +'%<br/>'+ 'sucess of numbers:'+ss[1]+'<br/>'+ 'length of file:'+ss[2]+'<br/>'+ 'velocity of trans:'+ss[3]+'<br/>'+ 'the time used:'+ss[4]+'<br/>'+ 'total time:'+ss[5]+'<br/>'+ 'other time:'+ss[6]+'<br/>'+ 'which is translating:'+ss[7]; if(ss[1] == ss[2]){ finished = true; $('statusInfo').innerHTML += "<br/><br/><br/>have done!"; $('btnSubmit').disabled = false; } } } function debug(obj){ var div = document.createElement("DIV"); div.innerHTML = "[debug]:"+obj; document.body.appendChild(div); } </script>
全部代码:
progressFileupload.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'progressFileupload.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <style type="text/css"> #progressBar {width:400px;height:12px;background:#FFFFFF;border:1px solid #000000;padding:1px} #progressBarItem{width:30%;height:100%;background:#FF0000;} </style> </head> <body> <iframe name=uploadiframe width=0 height=0></iframe> <form action="servlet/ProgressUploadServlet" method="post" enctype="multipart/form-data" target="uploadiframe" onsubmit="showStatus();"> <input type="file" name="file1" style="width:350px;"/><br/> <input type="file" name="file2" style="width:350px;"/><br/> <input type="file" name="file3" style="width:350px;"/><br/> <input type="submit" value="submit" id="btnSubmit"/> </form> <div id="status" style="display:none;"> uploadbar: <div id="progressBar"><div id="progressBarItem"></div></div> <div id="statusInfo"></div> </div> <script type="text/javascript"> var finished = true; function $(obj){ return document.getElementById(obj); } function showStatus(){ finished = false; $('status').style.display = 'block'; $('progressBarItem').style.width = '1%'; $('btnSubmit').disabled = true; setTimeout("requestStatus()",1000); } function requestStatus(){ if(finished) return; var req = createRequest(); req.open("GET","servlet/ProgressUploadServlet"); req.onreadystatechange = function(){callback(req);} req.send(null); setTimeout("requestStatus()",1000); } function createRequest(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else{ try{ return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ return new ActiveXObject("Microsoft.XMLHTTP"); } } return null; } function callback(req){ if(req.readyState == 4){ if(req.status != 200){ debug("error! req.status:"+req.status+""); return ; } debug("status.jsp return value:"+req.responseText); var ss = req.responseText.split("||"); $('progressBarItem').style.width = ''+ss[0]+'%'; $('statusInfo').innerHTML = 'end of total:'+ss[0] +'%<br/>'+ 'sucess of numbers:'+ss[1]+'<br/>'+ 'length of file:'+ss[2]+'<br/>'+ 'velocity of trans:'+ss[3]+'<br/>'+ 'the time used:'+ss[4]+'<br/>'+ 'total time:'+ss[5]+'<br/>'+ 'other time:'+ss[6]+'<br/>'+ 'which is translating:'+ss[7]; if(ss[1] == ss[2]){ finished = true; $('statusInfo').innerHTML += "<br/><br/><br/>have done!"; $('btnSubmit').disabled = false; } } } function debug(obj){ var div = document.createElement("DIV"); div.innerHTML = "[debug]:"+obj; document.body.appendChild(div); } </script> </body> </html>
UploadStatus.java
package com.test.temp; public class UploadStatus { private long bytesRead; private long contentLength; private int items; private long startTime = System.currentTimeMillis(); public long getBytesRead() { return bytesRead; } public void setBytesRead(long bytesRead) { this.bytesRead = bytesRead; } public long getContentLength() { return contentLength; } public void setContentLength(long contentLength) { this.contentLength = contentLength; } public int getItems() { return items; } public void setItems(int items) { this.items = items; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } }
UploadListener.java
package com.test.temp; import org.apache.commons.fileupload.ProgressListener; public class UploadListener implements ProgressListener { private UploadStatus status; public UploadListener(UploadStatus status){ this.status = status; } public void update(long bytesRead,long contentLength,int items){ status.setBytesRead(bytesRead); status.setContentLength(contentLength); status.setItems(items); } }
PorgressUploadServlet.java
package com.test.hello; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Iterator; 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.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.test.temp.UploadListener; import com.test.temp.UploadStatus; public class ProgressUploadServlet extends HttpServlet { /** * Constructor of the object. */ public ProgressUploadServlet() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control","no-store"); response.setHeader("Pragrma","no-cache"); response.setDateHeader("Expires",0); UploadStatus status = (UploadStatus) request.getSession(true).getAttribute("uploadStatus"); if(status == null){ response.getWriter().println("没有上传信息"); return; } long startTime = status.getStartTime(); long currentTime = System.currentTimeMillis(); long time = (currentTime - startTime)/1000 + 1; double velocity = ((double)status.getBytesRead())/(double)time; double totalTime = status.getContentLength()/velocity; double timeLeft = totalTime - time; int percent = (int)(100*(double)status.getBytesRead()/(double)status.getContentLength()); double length = ((double)status.getBytesRead())/1024/1024; double totalLength = ((double)status.getContentLength())/1024/1024; String value = percent +"||" + length + "||" +totalLength+"||"+ velocity+"||"+time+"||"+totalTime+"||"+timeLeft+"||"+status.getItems(); response.getWriter().println(value); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { UploadStatus status = new UploadStatus(); UploadListener listener = new UploadListener(status); request.getSession(true).setAttribute("uploadStatus",status); ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); upload.setProgressListener(listener); try{ List itemList = upload.parseRequest(request); for(Iterator it = itemList.iterator();it.hasNext();){ FileItem item = (FileItem)it.next(); if(item.isFormField()){ System.out.println("FormField:"+item.getFieldName()+"="+item.getString()); }else{ System.out.println("File:"+item.getName()); String fileName = item.getName().replace("/","\\"); fileName = fileName.substring(fileName.lastIndexOf("\\")); File saved = new File("D:\\upload_temp",fileName); saved.getParentFile().mkdirs(); InputStream ins = item.getInputStream(); OutputStream ous = new FileOutputStream(saved); byte[] tmp = new byte[1024]; int len = -1; while((len = ins.read(tmp)) != -1){ ous.write(tmp,0,len); } ous.close(); ins.close(); response.getWriter().println("已保存文件:"+saved); } } }catch(Exception e){ response.getWriter().println("上传发生错误:"+e.getMessage()); } // response.setContentType("text/html"); // PrintWriter out = response.getWriter(); // out // .println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); // out.println("<HTML>"); // out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); // out.println(" <BODY>"); // out.print(" This is "); // out.print(this.getClass()); // out.println(", using the POST method"); // out.println(" </BODY>"); // out.println("</HTML>"); // out.flush(); // out.close(); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>PostServlet</servlet-name> <servlet-class>com.test.hello.PostServlet</servlet-class> </servlet> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>test</servlet-name> <servlet-class>com.test.hello.test</servlet-class> </servlet> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>UploadServlet</servlet-name> <servlet-class>com.test.hello.UploadServlet</servlet-class> </servlet> <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>ProgressUploadServlet</servlet-name> <servlet-class>com.test.hello.ProgressUploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>PostServlet</servlet-name> <url-pattern>/servlet/PostServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>test</servlet-name> <url-pattern>/servlet/test</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/servlet/UploadServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ProgressUploadServlet</servlet-name> <url-pattern>/servlet/ProgressUploadServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
运行结果:
、