首先須要注意的問題:html
1 . form表單的內容格式要定義成multipart/form-data格式.
2 . 須要導入類庫:java
commons-fileupload-x.x.x.jar (下載地址:http://commons.apache.org/proper/commons-fileupload/)apache
commons-io-x.x.jar (下載地址:http://commons.apache.org/proper/commons-io/)post
使用開源Apache commons fileupload包上傳文件大概步驟以下:編碼
1 . 建立文件解析對象spa
DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload sfu = new ServletFileUpload(factory); sfu.setHeaderEncoding("utf-8"); //設置編碼 sfu.setFileSizeMax(1024*1024*1); //設置單個上傳文件最大字節數 sfu.setSizeMax(1024*1024*10); //設置整個表單最大字節數
2 . 建立一個集合保存表單數據.net
List<FileItem> formList = sfu.parseRequest(request);
3 . 讀取表單內容code
for (FileItem fileItem: formList) { //表單控件name屬性值 String fieldName = fileItem.getFieldName(); System.out.println("========控件名稱 : " + fieldName + "========"); if (fileItem.isFormField()) { //檢測表單類型 true:普通表單 false:表單包含文件數據 String fieldValue = fileItem.getString(); fieldValue = new String(fieldValue.getBytes("ISO-8859-1"), "UTF-8"); System.out.println("普通內容:" + fieldName + "=" + fieldValue); } else { String fileName = fileItem.getName(); long fileSize = fileItem.getSize(); File uploadFile = new File(saveDir, fileName); fileItem.write(uploadFile);//保存上傳文件 System.out.println("文件名 : " + fileName); System.out.println("文件大小 : " + fileSize + "byte"); System.out.println("文件保存路徑 : " + savePath); } }
具體事例以下:orm
1 . 源代碼htm
FileUpload.html
<!DOCTYPE html> <head> <title>testUpload</title> <meta charset="utf-8"> </head> <body> <h3>文件上傳</h3> <form enctype="multipart/form-data" method="post" action="FileUpload"> 文件描述:<input type="text" name="text" /><br/> 選擇文件:<input type="file" name="file1" /><br/> <input type="submit" value="上傳" /> </form> </body>
FileUpload.java
package cn.iborder.upload; import java.io.File; import java.io.IOException; import java.util.List; 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 FileUpload */ public class FileUpload extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public FileUpload() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setCharacterEncoding("UTF-8"); response.getWriter().println("請以POST方式上傳文件"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //保存路徑 String savePath = getServletContext().getRealPath("/temp1"); File saveDir = new File(savePath); if (!saveDir.exists()) { saveDir.mkdir(); } //建立核心上傳類實例 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload sfu = new ServletFileUpload(factory); sfu.setHeaderEncoding("utf-8"); //設置編碼 sfu.setFileSizeMax(1024*1024*1); //設置單個上傳文件最大字節數 sfu.setSizeMax(1024*1024*10); //設置整個表單最大字節數 //讀取表單數據 try { List<FileItem> formList = sfu.parseRequest(request); for (FileItem fileItem : formList) { //表單控件name屬性值 String fieldName = fileItem.getFieldName(); System.out.println("========控件名稱 : "+fieldName+"========"); if(fileItem.isFormField()){ //檢測表單類型 true:普通表單 false:表單包含文件數據 String fieldValue = fileItem.getString(); fieldValue = new String(fieldValue.getBytes("ISO-8859-1"), "UTF-8"); System.out.println("普通內容:" + fieldName + "=" + fieldValue); }else{ String fileName = fileItem.getName(); long fileSize = fileItem.getSize(); File uploadFile = new File(saveDir, fileName); fileItem.write(uploadFile); //保存上傳文件 System.out.println("文件名 : "+fileName); System.out.println("文件大小 : "+fileSize+"byte"); System.out.println("文件保存路徑 : "+savePath); } } } catch (FileUploadException e) { // TODO Auto-generated catch block System.out.println("獲取表單內容失敗!"); System.out.println(e.getMessage()); } catch (Exception e) { // TODO Auto-generated catch block System.out.println("保存上傳文件失敗!"); System.out.println(e.getMessage()); } } }
2 . 運行結果
相關類說明:
將請求消息實體中的每個項目封裝成單獨的DiskFileItem (FileItem接口的實現) 對象的任務
由 org.apache.commons.fileupload.FileItemFactory 接口的默認實現
org.apache.commons.fileupload.disk.DiskFileItemFactory 來完成。當上傳的文件項目比較小時,直接保存在內存中(速度比較快),比較大時,以臨時文件的形式,保存在磁盤臨時文件夾(雖然速度慢些,可是內存資源是有限的)。
構造方法
1) public DiskFileItemFactory()
採用默認臨界值和系統臨時文件夾構造文件項工廠對象。
2) public DiskFileItemFactory(int sizeThreshold,File repository)
採用參數指定臨界值和系統臨時文件夾構造文件項工廠對象。
2 . ServletFileUpload 類
org.apache.commons.fileupload.servlet.ServletFileUpload類是Apache文件上傳組件處理文件上傳的核心高級類(所謂高級就是不須要管底層實現,暴露給用戶的簡單易用的接口)。
使用其parseRequest(HttpServletRequest) 方法能夠將經過表單中每個HTML標籤提交的數據封裝成一個FileItem對象,而後以List列表的形式返回。使用該方法處理上傳文件簡單易用。
若是你但願進一步提升新能,你能夠採用 getItemIterator 方法,直接得到每個文件項的數據輸入流,對數據作直接處理。
在使用ServletFileUpload對象解析請求時須要根據DiskFileItemFactory對象的屬性sizeThreshold(臨界值)和repository(臨時目錄)來決定將解析獲得的數據保存在內存仍是臨時文件中,若是是臨時文件,保存在哪一個臨時目錄中?。因此,咱們須要在進行解析工做前構造好DiskFileItemFactory對象,經過ServletFileUpload對象的構造方法或setFileItemFactory()方法設置ServletFileUpload對象的fileItemFactory屬性。
3 . FileItem類
文件上傳時須要用到FileItem類,FileItem是一個接口,它的實現類是DiskFileItem。經常使用方法以下:
1)boolean isFormField()。isFormField方法用來判斷FileItem對象裏面封裝的數據是一個普通文本表單字段,仍是一個文件表單字段。若是是普通文本表單字段,返回一個true不然返回一個false。所以能夠用該方法判斷是不是普通表單域仍是文件上傳表單域。
2)String getName()。getName方法用來得到文件上傳字段中的文件名。
3)String getFieldName()。getFieldName方法用來返回表單標籤的name屬性的值。
4)void write(File file)。write方法將FileItem對象中的內容保存到某個指定的文件中。若是FileItem對象中的內容是保存在某個臨時文件中,該方法完成後,臨時文件能夠會被刪除。該方法也能夠將普通表單字段保存在一個文件中,但最主要的用途是把上傳的文件內容保存在本地文件系統中。
5)String getString()。getString()方法將FileItem對象中保存的數據流內容以一個字符串返回。它有兩個重載形式。public java.lang.String getString()和public java.lang.String getString(java.lang.String encodeing) throws java.io.UnsupportedEncodingException。前者使用缺省的字符集編碼將主體內容轉換成字符串,後者使用參數指定的字符集編碼。若是在讀取普通表單字段元素的內容時,出現了亂碼現象,能夠調用第二個方法,並傳入 正確的字符集編碼名稱。
6)String getContentType()。此方法用來得到上傳文件的類型,即標段字段元素描述頭屬性「content-type」的值,如image/jpeg。若是FileItem對象對應的是普通的表單字段,將返回null。
7)boolean isInMemory()。判斷FileItem對象封裝的數據是保存在內存中仍是硬盤中。
8)void delete()。此方法用來清空FileItem對象中封裝的主體內容,若是內容是被保存在臨時文件中,該方法會把臨時文件刪除。
9)InputStream getInputStream()。以流的形式返回上傳文件的主體內容。
10)long getSize()。返回上傳文件的大小。