java ajax 檔案上傳帶滾動條顯示
阿新 • • 發佈:2019-02-04
問題:實現檔案上傳並給出進度條顯示上傳過程資訊。
- 如何實現上傳的功能 ------使用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