自己封裝檔案上傳
- 需要的jar包
- 檔案上傳的幾大要素
- 構建檔案上傳構造方法
- 檔案上傳的執行流程
- 前端頁面檔案提交
- 服務端的處理
需要的jar包
commons-fileupload-1.3.1.jar
commons-io-2.2.jar
匯入了這兩個包就可以用java進行檔案上傳了
檔案上傳的幾大要素
- 上傳的目標路徑(就是要上傳到服務器的那個目錄)
- 需要有檔案名 (有時需要生成隨機id標識)
- 檔案大小限制
- 檔案型別限制
- 檔案上傳程序中的臨時檔案夾
- 檔案上傳程序中的記憶體快取大小
我們可以將以上的幾個屬性封裝成為類屬性
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;
}
}
其端頁面很靈活,可以自己動手制作
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/176399.html
標籤:其他
上一篇:vue專案優化
下一篇:前端三劍客(入門)
