標籤:protected tor pos 開源工具 核心 white actor Enctype form
曾經喜歡將自己的照片都喜歡上傳自己的空間,這就涉及到了web開發中的檔案上傳功能,檔案上傳功能是web開發中常見的功能,那他是怎麼上傳的呢?
檔案的上傳1. 簡介> 將一個用戶端的本地的檔案發送到伺服器中儲存。> 上傳檔案是通過流的形式將檔案發送給伺服器。2.前端表單的設定 > 向伺服器上傳一個檔案時,表單要使用post請求。> 表單的預設屬性enctype="application/x-www-form-urlencoded"-------------- 這個屬性的意思是請求體中的內容將會使用URL編碼> 上傳檔案的表單enctype需要設定為 multipart/form-data- multipart/form-data表示的是表單是一個多組件的表單- 如果類型設定為它,則我們的每一個表單項都會作為一個單獨的組件發送給伺服器。- 多個組件之間使用類似 -----------------------------7df2d08c0892 分割符來分開存在問題: 當表單設定為multipart/form-data時,我們request.getParameter()將失效,我們不能再通過該方法擷取請求參數。解決辦法:一般選擇採用apache的開源工具common-fileupload這個檔案上傳組件。這個common-fileupload上傳組件的jar包可以去apache官網上面下載,也可以在struts的lib檔案夾下面找到,struts上傳的功能就是基於這個實現的。common-fileupload是依賴於common-io這個包的,所以還需要下載這個包。前端代碼:
<form action="${pageContext.request.contextPath}/FileUpLoad" method="post" enctype="multipart/form-data"> 使用者:<input type="text" name="username"><br> <input type="file" name="photo"><br> <input type="file" name="photo1"><br> <input type="file" name="photo2"><br> <input type="submit" value="上傳"> </form>
前端:3. FileUpload> 我們一般情況下使用commons-fileupload-1.3.1.jar這個工具來解析多組件請求。> fileupload 依賴 commons-io 所以我們要是Filtupload需要同時匯入io包。 > 核心類:DiskFileItemFactory---------------- 工廠類,用於構建一個解析器執行個體。ServletFileUpload------------------- 解析器類,通過該類執行個體來解析request中的請求資訊。 FileItem- 工具會將我們請求中每一個組件,都封裝為一個FileItem對象,處理檔案上傳時,只需要調用該對象的方法- 方法:boolean isFormField() --> 當前表單項是否是一個普通表單項,true是普通表單項, false是檔案表單項String getContentType() --> 返回的是檔案的類型,是MIME值String getFieldName() --> 擷取表單項的name屬性值String getName() --> 擷取上傳的檔案的名字long getSize() --> 擷取檔案的大小String getString(String encoding) --> 擷取表單項的value屬性值,需要接受一個編碼作為參數。void write(File file) --> 將表單項中的內容寫入到磁碟中 > 使用步驟:1.擷取工廠類執行個體[DiskFileItemFactory]2.擷取解析器類執行個體[ServletFileUpload]3.解析request擷取FileItem[parseRequest()] [4] 細節第一個問題> 部分瀏覽器會將檔案的完整路徑作為檔案名稱發送。C:\Users\lilichao\Desktop\day20\圖片\蒙娜麗莎.jpg> 像這類檔案名稱我們需要截取一下字串,只擷取名字這部分,而不需要擷取路徑部分的資訊。通過如下代碼對檔案名稱進行截取字串的操作:if(name.contains("\\")){//如果包含則截取字串name = name.substring(name.lastIndexOf("\\")+1);} 第二個問題> 上傳的檔案有可能出現重名,後上傳的檔案會將先上傳的檔案覆蓋。> 解決:給檔案名稱加一個唯一的首碼。唯一標識_fennu.jpgUUID_fennu.jpg 第三個問題> 有些情況需要限制上傳檔案的大小。- 設定單個檔案大小為50KB:fileUpload.setFileSizeMax(1024*50);- 設定完單個檔案大小限制以後,一旦上傳的檔案超過限制,則會拋出如下異常:FileSizeLimitExceededException所有可以對該異常進行捕獲,當出現該異常時則設定一個錯誤訊息。 - 設定多個檔案的總大小為150KBfileUpload.setSizeMax(1024*150);- 當多個檔案的大小超出範圍時,會拋出如下異常SizeLimitExceededException 第四個問題> 當使用者上傳一個空的檔案,依然會將檔案儲存到硬碟上。> 在儲存檔案應該先對檔案的大小進行判斷,如果size為0,則不處理。 Servlet實現代碼:
package com.neuedu.servlet;import java.io.File;import java.io.IOException;import java.util.List;import java.util.UUID;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;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.FileUploadBase.FileSizeLimitExceededException;import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;@WebServlet("/FileUpLoad")public class FileUpLoad extends HttpServlet {private static final long serialVersionUID = 1L;protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //擷取項目ServletContext servletContext = request.getServletContext();//擷取項目路徑及檔案String realPath = servletContext.getRealPath("/upload"); File file = new File(realPath);//判斷檔案是否存在---不存在則建立出來 if (!file.exists()) {file.mkdir();}//建立一個工廠類DiskFileItemFactory factory=new DiskFileItemFactory(); //建立對象,完成上傳ServletFileUpload fileUpload =new ServletFileUpload(factory);//單檔案大小限制 1024b*50fileUpload.setFileSizeMax(1024*50);//上傳所有檔案限制大小fileUpload.setSizeMax(1024*150);//用這個對象解析request請求try {List<FileItem> fileList = fileUpload.parseRequest(request); for(FileItem item:fileList){ //isFormField()用於判斷當前表單項是否是一個普通表單項,true是普通表單項, false是檔案表單項 if (item.isFormField()) {//代表普通表單項----能擷取普通表單的參數 String fieldName = item.getFieldName(); //擷取表單項的name屬性值 String value = item.getString("utf-8"); //擷取表單項的value屬性值,需要接受一個編碼作為參數。 //輸出參數 System.out.println(fieldName+":"+value); }else { //代表上傳的檔案----能擷取普通表單的參數long size = item.getSize(); //擷取檔案的大小 if (size==0) {continue;}String contentType = item.getContentType(); // 返回的是檔案的類型,是MIME值 String name2 = item.getName(); // 擷取上傳的檔案的名字 String prName = UUID.randomUUID().toString();//利用時間戳記,製作唯一標示 prName=prName.replaceAll("-", ""); //字串操作,去掉時間戳記的- String reaName=prName+"_"+name2; //對檔案名稱進行拼串,創造出唯一檔案名,防止檔案名稱相同而覆蓋 String fieldName = item.getFieldName(); //擷取表單項的name屬性值 //輸出參數 System.out.println(size+":"+fieldName+":"+contentType+":"+name2); //item.write(new File("C:/Users/000/Desktop/234.jpg")); // 將表單項中的內容寫入到磁碟中 item.write(new File(realPath+"\\"+reaName));// 將表單項中的內容寫入到磁碟中 } }} catch(FileSizeLimitExceededException e){System.out.println("檔案過大");}catch (SizeLimitExceededException e) {System.out.println("超處上傳檔案最大限制");}catch ( Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
執行結果:控制台:檔案夾:
檔案的上傳