jQuery Uploadify + Apache Fileupload非同步上傳檔案範例
1、可以限制上傳檔案大小和類型,理論上任何類型的檔案都可以上傳(自己根據api配置即可);
2.後台使用Apache commons-fileupload-1.3.1.jar作為上傳工具包,本範例支援一次多檔案上傳;
3.文件上傳目錄可以任意指定,請在web.xml中配置;
Uploadify api 詳見http://www.uploadify.com/documentation/
FileUploadServlet
複製代碼代碼如下:
package com.xiaoxing.upload;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
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;
/**
* <h1>Apache Fileupload檔案上傳(2014-5-3)</h1>
* <p>1、如果你對本範例有興趣並想了解更多,歡迎加入Java私塾線上學習社群(329232140)</p>
* <p>2、針對這個例子小修小改便可移植到你的實際項目中。 </p>
*/
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 7579265950932321867L;
// 設定檔案預設上傳目錄(如果你沒有在web.xml中設定的話)
private String uploadDir = "c:/"; // 檔案上傳目錄
private String tempUploadDir = "c:/"; // 檔案暫時存放目錄(會話銷毀後由監聽器自動刪除)
/*
* (non-Javadoc)
* @see javax.servlet.GenericServlet#init()
* 如果在web.xml中配置了檔案上傳目錄則優先使用,判斷檔案目錄是否存在,不存在就建立。
*/
@Override
public void init() throws ServletException {
// 取得本項目所在真實硬碟目錄
String path = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
path = path.substring(0, path.indexOf("WEB-INF"));
// 判斷目標是否存在,不存在就建立
String uploadDir = path.concat(this.getInitParameter("uploadDir"));
String tempUploadDir = path.concat(this.getInitParameter("tempUploadDir"));
File f_uploadDir = new File(uploadDir);
File f_tempUploadDir = new File(tempUploadDir);
if (!f_uploadDir.exists()) {
f_uploadDir.mkdirs();
}
if (!f_tempUploadDir.exists()) {
f_tempUploadDir.mkdirs();
}
// 給變數賦值
this.uploadDir = uploadDir;
this.tempUploadDir = tempUploadDir;
}
/*
* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
* 不接收get方式提交的數據,回傳上傳失敗狀態碼。
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.setResponse(response);
PrintWriter out = response.getWriter();
out.print("{/"error/":/"-1/""); // 非法提交方式
}
/*
* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
* 上傳文件請求都是通常POST提交
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.setResponse(response); // 設定回應類型,以便前端解析
PrintWriter out = response.getWriter();
String result = "";
try {
// 檢查本次是否一個文件上傳請求
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
DiskFileItemFactory factory = new DiskFileItemFactory(); // 建立一個工廠基於磁碟的檔案項
factory.setRepository(new File(tempUploadDir)); // 設定儲存庫(確保安全的暫存位置時)
ServletFileUpload upload = new ServletFileUpload(factory); // 建立一個新的檔案上傳處理程序
upload.setSizeMax(1024 * 1024 * 100); // 設定總體要求尺寸限制(建議前後台分別設置,因為前後台用到了不同的插件)
List<FileItem> items = upload.parseRequest(request); // 解析請求
Iterator<FileItem> iter = items.iterator(); // 處理上傳的項目
while (iter.hasNext()) { //如果是一次上傳多個文件,那麼這裡會分別去保存
FileItem item = iter.next();
if (!item.isFormField()) { // 過濾表單裡的非檔案類型字段
if (!"".equals(item.getName())) { // 過濾非檔案類型的input
String s_name = item.getName(); // 取得原始檔名
int position = s_name.lastIndexOf(".");
String s_fileType = s_name.substring(position, s_name.length()); // 取得檔案後綴
String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
String s = uploadDir.concat("/").concat(date).concat("/");
//這裡按日期分目錄儲存文件
File sf = new File(s);
if (!sf.exists()) {
sf.mkdirs();
}
String s_filePath = s.concat(UUID.randomUUID().toString()).concat(s_fileType);
File path = new File(s_filePath);
item.write(path);
result += s_filePath.concat(",");
} else {
result = "";
break;
}
}
}
} else {
result = "";
}
String s_resultJSON = this.jointJSON(result); // 拼接回前端JSON
out.print(s_resultJSON);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.flush();
out.close();
}
}
/**
* 拼接JSON,將保存檔案的檔案名稱和日期目錄回傳給前端(前端可能需要這個路徑完成其他表單操作,例如將檔案路徑存放到資料庫)
* @param result JSON格式的字串
* @return
* @throws UnsupportedEncodingException
*/
private String jointJSON (String result) throws UnsupportedEncodingException {
String str = "";
if(!"".equals(result)) {
String rs[] = result.split(",");
StringBuffer buffer = new StringBuffer("{/"rows/":[");
for (int i = 0; i < rs.length; i++) {
String s_tmpName = rs[i];
s_tmpName = s_tmpName.substring(uploadDir.length(), s_tmpName.length());
buffer.append("{/"name/":/"").append(s_tmpName).append("/"},");
}
str = buffer.toString();
str = str.substring(0, str.length() - 1).concat("]}");
} else {
str = "{/"error/":/"-2/""; //上傳失敗
}
return str;
}
/**
* 設定回應類型ContentType為"application/x-json"
* @param response
*/
private void setResponse(HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
response.setHeader("cache-control", "no-cache");
}
}
test_upload.html
複製代碼代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery Uploadify + Apache Fileupload非同步上傳檔案範例(2014-5-3)</title>
<link rel="stylesheet" type="text/css" href="/js/uploadify/uploadify.css">
<script src="/js/jquery-1.9.0.js"></script>
<script src="/js/uploadify/jquery.uploadify.min.js"></script>
<script type="text/javascript">
$(function() {
$('#fileupload').uploadify({
'method' : 'post',
'buttonText' : 'flash上傳檔案',
'fileSizeLimit' : '1024KB',
'fileTypeExts' : '*.gif; *.jpg; *.png',
'swf' : '/js/uploadify/uploadify.swf',
'uploader' : '/upload', //這是上傳圖片的路徑,也就是我在web.xml裡設定的servlet
'onUploadSuccess' : function(file, data, response) { //圖片上傳成功後回傳資料在這裡處理
var ary = eval("(" + data + ")").rows;
for(var i = 0; i < ary.length; i++) {
$("#J_div").append("<img alt='圖片' src='/upload/images" + ary[i].name + "' width='200px' height='200px'>");
}
}
});
});
</script>
</head>
<body>
<h2>jQuery Uploadify + Apache Fileupload非同步上傳檔案範例(2014-5-3)</h2>
<p>1、可以限制上傳檔案大小和類型,理論上任何類型的檔案都可以上傳(自己根據api配置即可);</p>
<p>2、後台使用Apache commons-fileupload-1.3.1.jar作為上傳工具包,本範例支援一次多檔案上傳;</p>
<p>3、檔案上傳目錄可以任意指定,請在web.xml中設定;</p>
<p>4、對於已經上傳的圖片沒有查詢到這個頁面上,這部分留給你去做吧。 </p>
<p>Uploadify api 詳見http://www.uploadify.com/documentation/</p>
<p style="color: red">*如果你對這個例子有興趣並想了解更多,歡迎加入Java私塾線上學習社群(329232140)。 </p>
<input id="fileupload" type="file" name="img" multiple="multiple"/>
<div id="J_div"></div>
</body>
</html>
web.xml
複製代碼代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http ://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true" version="3.0">
<welcome-file-list>
<welcome-file>test_upload.html</welcome-file>
</welcome-file-list>
<servlet>
<description>專門處理上傳作業的servlet</description>
<servlet-name>FileUploadServlet</servlet-name>
<servlet-class>com.xiaoxing.upload.FileUploadServlet</servlet-class>
<init-param>
<description>檔案存放的正式目錄,可以自行設定</description>
<param-name>uploadDir</param-name>
<param-value>/upload/images/</param-value>
</init-param>
<init-param>
<description>檔案存放的臨時目錄,可以自行配置,裡的檔案由下面配置的監聽器自動刪除。 </description>
<param-name>tempUploadDir</param-name>
<param-value>/upload/temp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>
<listener>
<description>暫存檔案資源清理,工具包自備,不用我們來寫</description>
<listener-class>org.apache.commons.fileupload.servlet.FileCleanerCleanup</listener-class>
</listener>
</web-app>