給文件上傳添加進度條,整了兩天終於成功了。javascript
想要添加一個上傳的進度條,經過分析,應該是須要不斷的去訪問服務器,詢問上傳文件的大小。經過已上傳文件的大小,html
和上傳文件的總長度來評估上傳的進度。java
實現監聽器ProgressListener接口,能夠實時獲取上傳文件的長度。apache
public class FileUploadListener implements ProgressListener{ private HttpSession session; public FileUploadListener(HttpServletRequest request) { session = request.getSession(); FileState state = new FileState(); // 自定義FileState POJO類,儲存狀態信息 session.setAttribute("state", state); } @Override public void update(long readedBytes, long totalBytes, int currentItem) { // TODO Auto-generated method stub //System.out.println("update:"+readedBytes+";"+totalBytes+";"+currentItem); FileState state = (FileState) session.getAttribute("state"); state.setReadedBytes(readedBytes); // 已讀數據的長度 state.setTotalBytes(totalBytes); // 文件總長度 state.setCurrentItem(currentItem); // 正在保存第幾個文件 } }
FileState類json
public class FileState { private long readedBytes = 0L; // 已經上傳的字節數,單位:字節 private long totalBytes = 0L; // 全部文件的總長度,單位:字節 private int currentItem = 0; // 正在上傳第幾個文件 private long startTime=System.currentTimeMillis(); //開始上傳的時間,用於計算上傳的速度 public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } public long getReadedBytes() { return readedBytes; } public void setReadedBytes(long readedBytes) { this.readedBytes = readedBytes; } public long getTotalBytes() { return totalBytes; } public void setTotalBytes(long totalBytes) { this.totalBytes = totalBytes; } public int getCurrentItem() { return currentItem; } public void setCurrentItem(int currentItem) { this.currentItem = currentItem; } }
把監聽器FileUploadListener 添加到MyJakartaMultiPartRequest類中。MyJakartaMultiPartRequest類是Struts2源碼中的JakartaMultiPartRequest類。瀏覽器
在此類中添加進度監聽器,並覆蓋此類。緩存
private List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException { /* FileState fileState=new FileState(); servletRequest.getSession().setAttribute("state", fileState);*/ DiskFileItemFactory fac = createDiskFileItemFactory(saveDir); ServletFileUpload upload = new ServletFileUpload(fac); upload.setSizeMax(maxSize); // add 設置進度監聽器 upload.setProgressListener(new FileUploadListener(servletRequest)); // end return upload.parseRequest(createRequestContext(servletRequest)); }
在xml中配置服務器
<!-- 配置自定義文件類myrefactor,繼承MultiPartRequest重寫 --> <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="myrefactor" class="com.service.MyJakartaMultiPartRequest" scope="default" optional="true" />
actionsession
public class FileProgressAction { /** * 顯示文件上傳的進度 */ public String execute(){ HttpServletResponse response= ServletActionContext.getResponse(); response.setHeader("Cache-Control", "no-store"); //禁止瀏覽器緩存 response.setHeader("Pragrma", "no-cache"); //禁止瀏覽器緩存 response.setDateHeader("Expires", 0); //禁止瀏覽器緩存 Map session=ActionContext.getContext().getSession(); PrintWriter out = null; try { out = response.getWriter(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } FileState status = (FileState)session.get("state"); if(status == null){ //renderText("error"); return null; } long startTime = status.getStartTime(); //上傳開始時間 long currentTime = System.currentTimeMillis(); //如今時間 long time = (currentTime - startTime)/ 1000 + 1; //已傳輸的時間 單位:s //傳輸速度單位:byte/s double velocity = ((double)status.getReadedBytes()) / (double)time; //估計總時間 double totalTime = status.getTotalBytes(); //估計剩餘時間 double timeLeft = totalTime - time; //已經完成的百分比 int percent = (int)(100 * (double)status.getReadedBytes() / (double)status.getTotalBytes()); //已經完成數單位:m double length = ((double) status.getReadedBytes())/1024/1024; //總長度 單位:m double totalLength = ((double) status.getTotalBytes())/1024/1024; JSONObject json = new JSONObject(); json.put("percent", percent); json.put("length", length); json.put("totalLength", totalLength); json.put("velocity", velocity); json.put("time", time); json.put("totalTime", totalTime); json.put("timeLeft", timeLeft); json.put("fileNumber", status.getCurrentItem()); // System.out.println(json.toString()); out.print(json.toString()); return null; } }
jsjsp
var finished = true; //上傳是否結束 function showStatus(){ finished = false; /*$('#progressBarItem').attr('width','1%');*/ setTimeout('callback()',100); } function callback(){ if(finished) return; var url = 'fileProgressAction'; $.get(url,function(dataSrc){ var dataS=eval("("+dataSrc+")"); $('#progressBarItem').html("("+dataS.percent+"%"+")"); //alert(dataS.percent); }); setTimeout('callback()',100); }
jsp
<div style="width: 86px;float: left;margin-top: 15px;margin-left: 5px;"> <form action="filesUpload" method="post" enctype="multipart/form-data" style="margin-top: 16px;" onsubmit="return subClick()" > <a href="javascript:;" class="file"> <img alt="tip" src="images/upload.png" style="width: 55px;"> <input type="file" name="myFile" multiple="multiple" id="myFile" value="0" onchange="uplaodfileOnChange(this)"> </a> <input type="submit" value="上傳文件" style="margin-top: 3px;display: none;" id="sub" class="a-upload" onclick="wait()" /> <div id="fileDiv"></div> <div style="margin-left: 7px;margin-top: 3px;width: 300px;" id="messageDiv" class="tip">${message} </div> <%-- <span class="tip" id="perMessage"> ${request.perMessage} </span> --%> </form> <div id="error" class="tip" style="width: 1024px;"> <s:fielderror> </s:fielderror></div> </div>