簡介
FileUpload 是 Apache commons下面的一個子項目,用來實現Java環境下的文件上傳功能。
FileUpload鏈接
FileUpload 是基於Apache的Commons IO的,所以在使用之前需要先在BuildPath種添加Commons IO。
Commons IO鏈接
1.在項目種添加Commons IO和FileUpload
1.1下載Commons IO的最新版本
1.2下載FileUpLoad的最新版本
注:tar.gz是linux版本的
1.3分別把兩個jar文件復制到項目文件夾下
個人喜歡放在WEB-INF>lib下:
分別對兩個jar文件執行如下操作:
注意:兩個jar文件都要Add to Build Path,另外別忘了在java文件里還要import
2.按照Apache官網給出的指導使用文件上傳
官網指導鏈接
2.0在html文件或者jsp文件里創建一個上傳文件的表單
這里我創建的是一個jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>文件上傳</h1> <form method="POST" enctype="multipart/form-data" action="UpLoadFile" name="uploadForm"> 選擇一個文件: <input type="file" name="upfile"><br/> <br/> <input type="submit" value="上傳"> </form> </body> </html>
運行如下:
用到的一些類的說明:
DiskFileItemFactory——工廠類
ServletFileUpload——用於解析resquest,能從resquest中解析出裝有FileItem對象的一個List
FileItem——每個FileItem的實例都包含一個文件以及該文件的其他一些屬性(文件名、大小等)
注意:以下部分翻譯自官網指導。原文鏈接
2.1使用FileUpload
FileUpload可以通過多種不同的方式使用,具體的使用方式取決於您的應用要求。最簡單的方式,您將調用一種方法來解析servlet請求到一個List中。
2.2FileUpLoad是如何運行的
FileUpload可以解析一個請求(request),並向應用程序提供上傳的items(上傳的文件表單項目)的一個List。每個文件項目(items)都有一些你的應用程序可能感興趣的屬性,例如name、content type,每個items還能提供一個“InputStream”。
FileUpload使用FileItemFactory類來創建新的items,FileUpload附帶的FileItemFactory類的實例將項目的數據存儲在內存或磁盤上,具體取決於項目的大小(即數據字節數)。但是,可以自定義此行為。
2.3解析請求
在使用上傳的items之前,需要解析請求本身,確保請求實際上是一個文件上傳請求可用。
// Check that we have a file upload request boolean isMultipart = ServletFileUpload.isMultipartContent(request);
2.4最簡單的一種使用情況
- 只要上傳的項目足夠小,應保留在內存中。
- 較大的項目應寫入磁盤上的臨時文件。
- 不應該允許非常大的上傳請求。
- 內存中默認保留的內容的最大容量,上傳請求的最大允許大小以及臨時文件的位置是可以接受的(這一句是Google翻譯的)
// 創建工廠(這里用的是工廠模式) DiskFileItemFactory factory = new DiskFileItemFactory(); //獲取汽車零件清單與組裝說明書(從ServletContext中得到上傳來的數據) ServletContext servletContext = this.getServletConfig().getServletContext(); File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); //工廠把將要組裝的汽車的參數錄入工廠自己的系統,因為要根據這些參數開設一條生產線(上傳來的文件的各種屬性) factory.setRepository(repository); //此時工廠中已經有了汽車的組裝工藝、顏色等屬性參數(上傳來的文件的大小、文件名等) //執行下面的這一行代碼意味着根據組裝工藝等開設了一條組裝生產線 ServletFileUpload upload = new ServletFileUpload(factory);
這樣我門就獲得了一個List。
Servlet完整代碼:
package com.feipeng8848; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Iterator; import java.util.List; import javax.servlet.ServletContext; 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; /** * Servlet implementation class UpLoadExcelServlet */ public class UpLoadExcelServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public UpLoadExcelServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE html>\n"); out.println("<head><title>PageTitle</title></head>"); out.println("<body>"); out.println("<p>文件已經上傳成功</p>"); out.println("</body>"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); System.out.println("doPost"); boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart) { System.out.println("True"); // 創建工廠(這里用的是工廠模式) DiskFileItemFactory factory = new DiskFileItemFactory(); //獲取汽車零件清單與組裝說明書(從ServletContext中得到上傳來的數據) ServletContext servletContext = this.getServletConfig().getServletContext(); File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); //工廠把將要組裝的汽車的參數錄入工廠自己的系統,因為要根據這些參數開設一條生產線(上傳來的文件的各種屬性) factory.setRepository(repository); //此時工廠中已經有了汽車的組裝工藝、顏色等屬性參數(上傳來的文件的大小、文件名等) //執行下面的這一行代碼意味着根據組裝工藝等開設了一條組裝生產線 ServletFileUpload upload = new ServletFileUpload(factory); //解析請求 try { //把零件送給生產線,出來的就是一輛組裝好的汽車(把request轉成FileItem的實例) List<FileItem> items = upload.parseRequest(request); Iterator<FileItem> iter = items.iterator(); while (iter.hasNext()) { FileItem item = iter.next(); //創建文件輸出流 File file=new File("D:\\b.xlsx"); if(!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } FileOutputStream fos=new FileOutputStream(file); //創建輸入流 InputStream fis=(InputStream) item.getInputStream(); //從輸入流獲取字節數組 byte b[]=new byte[1]; //讀取一個輸入流的字節到b[0]中 int read=fis.read(b); while(read!=-1) { fos.write(b,0,1); read=fis.read(b); } fis.close(); fos.flush(); fos.close(); //打印List中的內容(每一個FileItem的實例代表一個文件,執行這行代碼會打印該文件的一些基本屬性,文件名,大小等) System.out.println(item); } System.out.println("循環輸出完成"); } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { System.out.println("False"); } } }
選擇一個文件:
輸出:
輸出的完整內容:
doPost True name=PRICIPLE_k.png, StoreLocation=C:\Users\k\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\DBControler\upload_cae42561_32ce_45d4_9009_
ec94523a4b02_00000000.tmp, size=24914 bytes, isFormField=false, FieldName=upfile 循環輸出完成