1. 程式人生 > >java ajax 檔案上傳帶滾動條顯示

java ajax 檔案上傳帶滾動條顯示

問題:實現檔案上傳並給出進度條顯示上傳過程資訊。

  • 如何實現上傳的功能  ------使用apache的FileUpload元件上傳檔案
  • 如何實現上傳檔案的監聽功能 ------使用ProgressListener監聽檔案狀態
  • 如何實現記錄上傳狀態的功能 ------使用session儲存檔案的狀態
  • 客戶端如何狀態的實時顯示 -------客戶端使用AJAX來查詢上傳的狀態
思路:

客戶端:介面的提交的時候使用<iframe 來實現模擬的無重新整理提交,然後在使用ajax來週期的訪問servlet並返回sesson中最新的狀態資訊。

伺服器端:在servlet介紹到請求的時候,區分請求的型別是上傳的請求還是ajax詢問的請求,如果是上傳的請求,則執行上傳的方法,並啟動監聽儲存上傳狀態到session中。

原始檔介面和執行介面:                
抽象出文件上傳過程中需要用到的資料資訊,檔案的總大小、已上傳大小、開始時間。
package com.test.entity;

public class Upload {
	private long totalSize;										//總大小
	private long startTime = System.currentTimeMillis();		//開始時間
	private long uploadSize;									//已上傳的大小
	public long getTotalSize() {
		return totalSize;
	}
	public void setTotalSize(long totalSize) {
		this.totalSize = totalSize;
	}
	public long getStartTime() {
		return startTime;
	}
	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}
	public long getUploadSize() {
		return uploadSize;
	}
	public void setUploadSize(long uploadSize) {
		this.uploadSize = uploadSize;
	}
}

設定監聽,實現介面ProgressListener

package com.test.lister;

import org.apache.commons.fileupload.ProgressListener;

import com.test.entity.Upload;

public class UploadLister implements ProgressListener{
<span style="white-space:pre">	</span>private Upload upload = null;
<span style="white-space:pre">	</span>public UploadLister(Upload upload){
<span style="white-space:pre">		</span>this.upload = upload;
<span style="white-space:pre">	</span>}

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * @param uploadSize 已上傳大小
<span style="white-space:pre">	</span> * @param totalSize 總大小
<span style="white-space:pre">	</span> * @param items 上傳第幾個(暫時用不到)
<span style="white-space:pre">	</span> */
<span style="white-space:pre">	</span>public void update(long uploadSize,long totalSize,int items) {
<span style="white-space:pre">		</span>upload.setUploadSize(uploadSize);
<span style="white-space:pre">		</span>upload.setTotalSize(totalSize);
<span style="white-space:pre">	</span>}
}

上傳服務的servlet:
package com.test.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.test.lister.UploadLister;

@SuppressWarnings("serial")
public class Upload extends HttpServlet {

	public Upload() {
		super();
	}

	public void destroy() {
		super.destroy(); 
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		com.test.entity.Upload upload = new com.test.entity.Upload();

		UploadLister lister = new UploadLister(upload);

		ServletFileUpload servletFileUpload = new ServletFileUpload(
				new DiskFileItemFactory());

		// 設定上傳監聽器
		servletFileUpload.setProgressListener(lister);
		//使用session儲存檔案的狀態
		request.getSession().setAttribute("upload", upload);

		List list = null;
		try {
			list = servletFileUpload.parseRequest(request);
		} catch (FileUploadException e) {
			e.printStackTrace();
		}

		for (Iterator iter = list.iterator(); iter.hasNext();) {
			// 得到檔案物件
			FileItem fileItem = (FileItem) iter.next();
			// 是表單才進行處理
			if (fileItem.isFormField()) {
				break;
			}
			// 同一linux和windows的路徑分隔符
			String name = fileItem.getName().replaceAll("/", "\\");
			// 得到檔名
			int index = name.lastIndexOf("\\");
			String fileFileName = "";
			if (index == -1) {
				fileFileName = name;
			} else {
				fileFileName = name.substring(index + 1);
			}

			InputStream fileInputStream = fileItem.getInputStream();

			String path = request.getRealPath("/upload");
			// 也可不用自己寫實現方法直接使用,fileItem.write(uploadFile);
			File uploadFile = new File(path, fileFileName);
			// 首先要確認路徑是否存在
			uploadFile.getParentFile().mkdirs();
			// 檢查檔案是否已經存在
			if (!uploadFile.exists()) {
				// 建立檔案
				uploadFile.createNewFile();
			}
			FileOutputStream out2 = new FileOutputStream(uploadFile);
			// 開始copy檔案

			@SuppressWarnings("unused")
			int len = 0;// 每次讀取的位元組數
			byte[] bytes = new byte[1024];
			while ((len = fileInputStream.read(bytes, 0, bytes.length)) != -1) {
				out2.write(bytes);
			}
			out2.flush();
			out2.close();
			fileInputStream.close();
		}
		out.flush();
		out.close();
	}

	public void init() throws ServletException {

	}

}

重新整理進度資訊的servlet
package com.test.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.test.lister.UploadLister;

@SuppressWarnings("serial")
public class Upload extends HttpServlet {

	public Upload() {
		super();
	}

	public void destroy() {
		super.destroy(); 
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		com.test.entity.Upload upload = new com.test.entity.Upload();

		UploadLister lister = new UploadLister(upload);

		ServletFileUpload servletFileUpload = new ServletFileUpload(
				new DiskFileItemFactory());

		// 設定上傳監聽器
		servletFileUpload.setProgressListener(lister);
		//使用session儲存檔案的狀態
		request.getSession().setAttribute("upload", upload);

		List list = null;
		try {
			list = servletFileUpload.parseRequest(request);
		} catch (FileUploadException e) {
			e.printStackTrace();
		}

		for (Iterator iter = list.iterator(); iter.hasNext();) {
			// 得到檔案物件
			FileItem fileItem = (FileItem) iter.next();
			// 是表單才進行處理
			if (fileItem.isFormField()) {
				break;
			}
			// 同一linux和windows的路徑分隔符
			String name = fileItem.getName().replaceAll("/", "\\");
			// 得到檔名
			int index = name.lastIndexOf("\\");
			String fileFileName = "";
			if (index == -1) {
				fileFileName = name;
			} else {
				fileFileName = name.substring(index + 1);
			}

			InputStream fileInputStream = fileItem.getInputStream();

			String path = request.getRealPath("/upload");
			// 也可不用自己寫實現方法直接使用,fileItem.write(uploadFile);
			File uploadFile = new File(path, fileFileName);
			// 首先要確認路徑是否存在
			uploadFile.getParentFile().mkdirs();
			// 檢查檔案是否已經存在
			if (!uploadFile.exists()) {
				// 建立檔案
				uploadFile.createNewFile();
			}
			FileOutputStream out2 = new FileOutputStream(uploadFile);
			// 開始copy檔案

			@SuppressWarnings("unused")
			int len = 0;// 每次讀取的位元組數
			byte[] bytes = new byte[1024];
			while ((len = fileInputStream.read(bytes, 0, bytes.length)) != -1) {
				out2.write(bytes);
			}
			out2.flush();
			out2.close();
			fileInputStream.close();
		}
		out.flush();
		out.close();
	}

	public void init() throws ServletException {

	}

}

上傳的檔案的jsp介面
<html>
  <head>
    <base href="<%=basePath%>">
    <title>使用Ajax、Jquery進行檔案上傳,帶進度條</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="struts2 ajax upload progress">
	<meta http-equiv="description" content="file upload by struts2 and ajax and jquery progress">
	<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
	<script type="text/javascript">
		var over = false;
		var inter;
		function upload(){
			over = false;
			$("#state").html("");
			$("#progress").css("width","0");
			$("input[type=submit]").attr("disabled",true);
			$("#progress").css("width","0%");
			$("#state").html("正在上傳... 總大小:0MB,已上傳:0MB,0%,已用時:0秒,剩餘時間:0秒,速度:0KB/S");
			inter = setInterval(req,1000);
		}
		function req(){
			//如果上傳已經完成
			if(over){
				clearInterval(inter);
				return;
			}
			var url = "upload/AjaxServlet";
			$.get(url,function(date){
				var state = date.split("-");
				$("#state").html("正在上傳... 總大小:"+state[4]+"MB,已上傳:"+state[3]+"MB,"+state[2]+"%,已用時:"+state[0]+"秒,剩餘時間:"+state[5]+"秒,速度:"+state[1]+"KB/S");
				$("#progress").animate({width:state[2]+"%"},500);
				if(state[3] == state[4]){
					over = true;
					$("input[type=submit]").attr("disabled",false);
					$("#state").html("上傳已完成,總大小:"+state[4]+"MB,已上傳:"+state[3]+"MB,"+state[2]+"%,已用時:"+state[0]+"秒,剩餘時間:"+state[5]+"秒,速度:"+state[1]+"KB/S");
				}
			});	
		}
	</script>
  </head>
  
  <body>
  	<form action="servlet/Upload" method="post" enctype="multipart/form-data" target="upload_iframe" onsubmit="upload()">
  		<p><input type="file" name="file" id="file"></p>
  		<p><input type="submit" value="上傳檔案"></p> 
  	</form>
  	<iframe name="upload_iframe" width="0" height="0" frameborder="0"></iframe>
  	<div id="state">
  	</div>
  	<div id="progress" style="background: #728820; height: 20px; width: 0">
  	</div>
  </body>
</html>

配置檔案資訊
<?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>
    <servlet-name>AjaxServlet</servlet-name>
    <servlet-class>com.test.servlet.AjaxServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>Upload</servlet-name>
    <servlet-class>com.test.servlet.Upload</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>AjaxServlet</servlet-name>
    <url-pattern>/upload/AjaxServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Upload</servlet-name>
    <url-pattern>/servlet/Upload</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>upload.jsp</welcome-file>
  </welcome-file-list>
</web-app>
用到的公共檔案:jquery-1.7.1.js  、commons-fileupload-1.2.2.jar、 commons-io-2.0.1.jar