commons-fileupload-1.3.1.jar
commons-io-2.2.jar
匯入了這兩個包就可以用java進行檔案上傳了
我們可以將以上的幾個屬性封裝成為類屬性
private static final String DEFAULT_TEMP_FILEPATH = "D:\\temp\\buffer\\";//預設臨時路徑
private static final String[] DEFAULT_FILETYPE = {"jpg", "png", "bmp", "gif"};//預設上傳的檔案型別
private static final int DEFAULT_SIZE_THRESHOLD = 1024 * 4;//預設快取大小4k
private static final int DEFAULT_SIZE_MAX = 1024 * 5000;//預設最大檔案大小5mb
private String fileLoadPath; //上傳目標的路徑
private String fileName; //檔名
private String tempFilePath; //臨時資料夾
private String[] fileType; //允許的檔案型別
private int sizeThreshold; //上傳快取區大小
private int sizeMax; //上傳檔案最大大小限制
private DiskFileItemFactory factory; //磁碟檔案工廠
private ServletFileUpload upload; //檔案上傳物件
前屬性為預設值。
我們進行檔案上傳是肯定要使用上面這個物件進行操作,那麼我們得在這個物件範例化的時候做一些事情,比如初始化一些重要引數:
第一個構造方法:
/**
* 自定義屬性構造方法
*
* @param loadPath
* @param tempFilePath
* @param fileType
* @param sizeThreshold
* @param sizeMax
*/
public FileLoadUtil(String loadPath, String tempFilePath, String[] fileType, int sizeThreshold, int sizeMax) {
this.fileLoadPath = loadPath; //上傳的目標路徑
this.tempFilePath = tempFilePath; //臨時資料夾
this.fileType = fileType; //指定檔案型別
this.sizeThreshold = sizeThreshold; //快取大小
this.sizeMax = sizeMax; //檔案最大允許大小
}
第二個構造方法:
/**
* 預設屬性構造方法
* @param loadPath
*/
public FileLoadUtil(String loadPath) {
this.tempFilePath = DEFAULT_TEMP_FILEPATH; //設定預設的臨時路徑
this.fileType = DEFAULT_FILETYPE; //設定預設執行的檔案型別
this.sizeThreshold = DEFAULT_SIZE_THRESHOLD; //設定預設的快取大小
this.sizeMax = DEFAULT_SIZE_MAX; //設定預設的最大檔案允許大小
this.fileLoadPath = loadPath; //設值檔案上傳目標路徑
this.factory = new DiskFileItemFactory(); //範例化磁碟檔案工廠物件
}
第三個:
/**
* 保留構造方法
*/
public FileLoadUtil(){
}
接下來就是一些get 和 set的方法的定義了,這裡不會列出,後面會一起把完整的程式碼列出來。
我將此執行流程分為一個個的方法,每個方法都作為一個模組,這樣可以方便以後擴充套件和維護。
/**
* 建立臨時資料夾
* @return 成功返回true失敗返回false
*/
public boolean createTempDirectory() {
File tempPatchFile = new File("D:\\temp\\buffer\\");
//檢查目錄是否存在
if (!tempPatchFile.exists()) {
//建立該目錄
if (!tempPatchFile.mkdirs()) {
return false;
}
}
return true;
}
/**
* 設定檔案上傳引數
*/
public void setUploadParam() {
//設定快取大小
factory.setSizeThreshold(sizeThreshold);
//設定臨時資料夾
factory.setRepository(new File(tempFilePath));
//範例化檔案上傳物件
upload = new ServletFileUpload(factory);
//設定上傳檔案最大大小
upload.setSizeMax(sizeMax);
}
/**
* 多檔案上傳的的核心
* @param fileItems
* @return 返回上傳的檔名稱集合
* @throws Exception
*/
public List<String> processFormFile(List<FileItem> fileItems) throws Exception {
//存放檔名的集合
List<String> nameArr = new ArrayList<>();
//用於迭代遍歷fileItems
Iterator<FileItem> itemIterator = fileItems.iterator();
//遍歷fileItems集合
while (itemIterator.hasNext()) {
//獲取List<FileItem>集合中的每一個FileItem項
FileItem fileItem = itemIterator.next();
//判斷該表單是否為file型別(file:false,nofile:true)
if (!fileItem.isFormField()) {
String name;
//此處上傳單個檔案
if((name = fileUploading(fileItem)) != null)
//將檔名儲存至集合
nameArr.add(name);
}
}
return nameArr;
}
/**
* 檔案上傳方法,包括檔案型別判斷
* @param fileItem
* @return null/string
* @throws Exception
*/
private String fileUploading(FileItem fileItem) throws Exception {
String fileName = fileItem.getName();
//將檔案型別陣列轉換為ArrayList集合
List<String> fileType = Arrays.asList(this.fileType);
//獲取檔案字尾名
String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
//如果不匹配返回true
if (!fileType.contains(ext)) {
System.out.println("檔案型別不符合");
} else {
//檔名不能為空和空字元
if (fileName != null && !fileName.equals("")) {
//目標檔案物件
File fullFile = new File(fileName);
//上傳路徑物件
File fileSave = new File(fileLoadPath, fullFile.getName());
//將檔案上傳
fileItem.write(fileSave);
//返回檔名
return fileName;
}
}
return null;
}
以上4個方法就可以實現多檔案上傳了,接下來只剩下一個主調方法來將以上的流程組合起來:
/**
* 預設的檔案上傳主調方法
* @param req
* @return 上傳成功的檔案集合
* @throws Exception
*/
public List<String> defUpload(HttpServletRequest req) throws Exception{
//先創臨時資料夾
if(!this.createTempDirectory()){
System.out.println("建立資料夾失敗");
}
//設定檔案上傳引數
this.setUploadParam();
List<FileItem> fileItems = null;
//判斷是否為檔案上傳表單
if(ServletFileUpload.isMultipartContent(req)) {
//從請求中獲取檔案集合
fileItems = upload.parseRequest(req);
//返回檔案上傳後的檔名稱集合
return this.processFormFile(fileItems);
}
return null;
}
至此這個類已經寫好了。
我們通常有兩種方式提交檔案,一個是通過form表單提交,一個是通過ajax非同步提交,那麼在這個案例中,我將通過使用ajax來提交檔案。
<input type = "file"/>
<input type = "file"/>
<input type = "file"/>
<button id = "cli">上傳</button>
上面我定義了幾個input標籤,型別文件案型別,其中沒有用到form表單。當我點選上傳按鈕的時候就會將這三個標籤中的檔案上傳至伺服器。
以下是我的js程式碼,利用了jquery的ajax:
$("#cli").click(function(){
var form = new FormData();
var fileobjs = new Array();
for(var i = 0; i < $("input[type='file']").length; i++) {
var ele = document.getElementsByTagName("input");
fileobjs[i] = ele[i].files[0]
}
for(var i = 0; i < fileobjs.length; i++) {
form.append("img", fileobjs[i]);
}
fileUpload(form)
})
上面是獲取input中的檔案並封裝到FormData的一個過程,然後再將form中的資料交給fileUpload提交到伺服器上傳。
現在看看fileUpload方法:
function fileUpload(form) {
$.ajax({
type:"post",
async:false,
url:"/MyFileUpload/file",
data:form,
dataType:"text",
processData : false, // 使資料不做處理
contentType : false, // 不要設定Content-Type請求頭
success:function (data) {
},
error:function(){
alert("FBI Waring")
}
})
}
我們在這裡要加上這兩個屬性設定 processData : false, contentType : false,這樣請求到伺服器是就不會是個物件了,保證了資料的可上傳性。
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//檔案上傳的工具類
FileLoadUtil fileLoadUtil = new FileLoadUtil("D:/img");
try {
//獲取到成功上傳的檔案集合
List<String> list = fileLoadUtil.defUpload(req);
if (list != null) {
for (String string : list) {
System.out.println(string + "已成功上傳...");
}
System.out.println(list.size()+"個檔案已成功上傳");
} else {
System.out.println("上傳失敗");
}
} catch (Exception e) {
e.printStackTrace();
}
}
最後我把封裝好的工具類奉上,如果是初學可以參考一下,嘗試自己改變其中的定義,讓他變得更好:
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* @description:
* @author: LiWenJie
* @time: 2020/9/11 11:35
*/
public class FileLoadUtil {
private static final String DEFAULT_TEMP_FILEPATH = "D:\\temp\\buffer\\";//預設臨時路徑
private static final String[] DEFAULT_FILETYPE = {"jpg", "png", "bmp", "gif"};//預設上傳的檔案型別
private static final int DEFAULT_SIZE_THRESHOLD = 1024 * 4;//預設快取大小4k
private static final int DEFAULT_SIZE_MAX = 1024 * 5000;//預設最大檔案大小5mb
private String fileLoadPath; //上傳目標的路徑
private String fileName; //檔名
private String tempFilePath; //臨時資料夾
private String[] fileType; //允許的檔案型別
private int sizeThreshold; //上傳快取區大小
private int sizeMax; //上傳檔案最大大小限制
private DiskFileItemFactory factory; //磁碟檔案工廠
private ServletFileUpload upload; //檔案上傳物件
/**
* 自定義構造方法
*
* @param loadPath
* @param tempFilePath
* @param fileType
* @param sizeThreshold
* @param sizeMax
*/
public FileLoadUtil(String loadPath, String tempFilePath, String[] fileType, int sizeThreshold, int sizeMax) {
this.fileLoadPath = loadPath;
this.tempFilePath = tempFilePath;
this.fileType = fileType;
this.sizeThreshold = sizeThreshold;
this.sizeMax = sizeMax;
}
/**
* 預設構造方法
* @param loadPath
*/
public FileLoadUtil(String loadPath) {
this.tempFilePath = DEFAULT_TEMP_FILEPATH;
this.fileType = DEFAULT_FILETYPE;
this.sizeThreshold = DEFAULT_SIZE_THRESHOLD;
this.sizeMax = DEFAULT_SIZE_MAX;
this.fileLoadPath = loadPath;
this.factory = new DiskFileItemFactory();
}
/**
* 保留構造方法
*/
public FileLoadUtil(){
}
/**
* 返回預設的臨時資料夾
* @return
*/
public static String getDefaultTempFilepath() {
return DEFAULT_TEMP_FILEPATH;
}
/**
* 獲取上傳檔案的路徑
* @return
*/
public String getFileLoadPath() {
return fileLoadPath;
}
public void setFileLoadPath(String fileLoadPath) {
this.fileLoadPath = fileLoadPath;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getTempFilePath() {
return tempFilePath;
}
public void setTempFilePath(String tempFilePath) {
this.tempFilePath = tempFilePath;
}
public String[] getFileType() {
return fileType;
}
public void setFileType(String[] fileType) {
this.fileType = fileType;
}
public int getSizeThreshold() {
return sizeThreshold;
}
public void setSizeThreshold(int sizeThreshold) {
this.sizeThreshold = sizeThreshold;
}
public int getSizeMax() {
return sizeMax;
}
public void setSizeMax(int sizeMax) {
this.sizeMax = sizeMax;
}
/**
* 建立臨時資料夾
* @return
*/
public boolean createTempDirectory() {
File tempPatchFile = new File("D:\\temp\\buffer\\");
//檢查目錄是否存在
if (!tempPatchFile.exists()) {
//建立該目錄
if (!tempPatchFile.mkdirs()) {
return false;
}
}
return true;
}
/**
* 設定檔案上傳引數
*/
public void setUploadParam() {
//設定快取大小
factory.setSizeThreshold(sizeThreshold);
//設定臨時資料夾
factory.setRepository(new File(tempFilePath));
//範例化檔案上傳物件
upload = new ServletFileUpload(factory);
//設定上傳檔案最大大小
upload.setSizeMax(sizeMax);
}
/**
* 處理請求的檔案集合
* @param fileItems
* @return
* @throws Exception
*/
public List<String> processFormFile(List<FileItem> fileItems) throws Exception {
//存放檔名的集合
List<String> nameArr = new ArrayList<>();
//用於迭代遍歷fileItems
Iterator<FileItem> itemIterator = fileItems.iterator();
//遍歷fileItems集合
while (itemIterator.hasNext()) {
//獲取List<FileItem>集合中的每一個FileItem項
FileItem fileItem = itemIterator.next();
//判斷該表單是否為file型別(file:false,nofile:true)
if (!fileItem.isFormField()) {
String name;
//此處上傳單個檔案
if((name = fileUploading(fileItem)) != null)
//將檔名儲存至集合
nameArr.add(name);
}
}
return nameArr;
}
/**
* 檔案上傳方法,包括檔案型別判斷
* @param fileItem
* @return
* @throws Exception
*/
private String fileUploading(FileItem fileItem) throws Exception {
String fileName = fileItem.getName();
//將檔案型別陣列轉換為ArrayList集合
List<String> fileType = Arrays.asList(this.fileType);
//獲取檔案字尾名
String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
//如果不匹配返回true
if (!fileType.contains(ext)) {
System.out.println("檔案型別不符合");
} else {
//檔名不能為空和空字元
if (fileName != null && !fileName.equals("")) {
//目標檔案物件
File fullFile = new File(fileName);
//上傳路徑物件
File fileSave = new File(fileLoadPath, fullFile.getName());
//將檔案上傳
fileItem.write(fileSave);
//返回檔名
return fileName;
}
}
return null;
}
/**
* 預設的檔案上傳主調方法
* @param req
* @return 上傳成功的檔案集合
* @throws Exception
*/
public List<String> defUpload(HttpServletRequest req) throws Exception{
//先創臨時資料夾
if(!this.createTempDirectory()){
System.out.println("建立資料夾失敗");
}
//設定檔案上傳引數
this.setUploadParam();
List<FileItem> fileItems = null;
//判斷是否為檔案上傳表單
if(ServletFileUpload.isMultipartContent(req)) {
//從請求中獲取檔案集合
fileItems = upload.parseRequest(req);
//返回檔案上傳後的檔名稱集合
return this.processFormFile(fileItems);
}
return null;
}
}
其端頁面很靈活,可以自己動手製作