圖片上傳之fileupload
最近學習了圖片上傳這個功能,這個功能比較常見,因此來整理一下,瞭解上傳的基本原理,以便後期遇到圖片上傳功能可以很快上手。
要說圖片上傳,我們先來說一下圖片上傳後儲存的兩種方式:一種是將圖片儲存到資料庫中;一種是將圖片儲存在伺服器檔案目錄中。首先,對於將圖片儲存到資料庫中適合資料量小的情況,因為寫到資料庫的圖片需要轉換成二進位制流的格式,佔用資料空間比較,適合少量圖片的儲存,比如,系統中某些小圖示,寫到資料庫中的優點是比較安全,不容易被使用者不小心刪除。但是,圖片存在資料庫的操作方面的侷限性太大,還要拼湊sql,db
server還要parse sql, write into file,讀寫效能不高,備份越來越大。
下面我將以圖片儲存在伺服器目錄中的形式,介紹一下fileupload方式的圖片上傳。common-fileupload元件是apache的一個開源專案之一,可以從
下面我就講一下基本實現:
首先需要在lib目錄下引入:commons-io-1.3.2.jar和commons-fileupload-1.3.1.jar。
前端程式碼:
<span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <html> <head> <title>fileUpload</title> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> </head> <body> <form action="./servlet/FileUploadServlet" method="post" enctype="multipart/form-data" name="form1"> <input type="file" name="file"> <input type="submit" name="Submit" value="upload"> </form> <form action="./servlet/HelloWord" method="post"> <input type="submit"/> </form> <form name="uploadform" method="POST" action="./servlet/FileUploadServlet" ENCTYPE="multipart/form-data"> <table border="1" width="450" cellpadding="4" cellspacing="2" bordercolor="#9BD7FF"> <tr><td width="100%" colspan="2"> 檔案1:<input name="x" size="40" type="file"> </td></tr> <tr><td width="100%" colspan="2"> 檔案2:<input name="y" size="40" type="file"> </td></tr> <tr><td width="100%" colspan="2"> 檔案3:<input name="z" size="40" type="file"> </td></tr> </table> <br/><br/> <table> <tr><td align="center"><input name="upload" type="submit" value="開始上傳"/></td></tr> </table> </form> </body> </html> </span>
注意:檔案上傳在前端要使用file標籤,採用form表單提交enctype=" multipart/form-data "。關於enctype="multipart/form-data"的說明:在jsp中使用了該格式,對應的Servlet就不能使用request.getParameter()取得引數,要使用ServletFileUpload物件的parseRequest方法先把request物件中的資料解析,然後,使用解析出的元素的isFormField標誌,配合getFieldName方法來獲取資料。
java程式碼:
<span style="font-size:14px;">package uploadPack;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@SuppressWarnings("serial")
public class FileUploadServlet extends HttpServlet {
//儲存圖片到資料庫類的方法
ItemManager itemManager = new ItemManagerImpl() ;
//用於存放上傳檔案
private File uploadPath;
//用於存放臨時檔案的目錄
private File tempPath;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//從test_upload.jsp中拿取資料,因為上傳頁的編碼格式跟一般的不同,使用的是enctype="multipart/form-data"
//form提交採用multipart/form-data,無法採用req.getParameter()取得資料
//DiskFileItemFactory:建立FileItem物件的工廠,這個工廠類中可以配置記憶體緩衝池大小和臨時檔案的目錄
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(4096);
// the location for saving data that is larger than getSizeThreshold()
factory.setRepository(tempPath);
//ServletFileUpload:負責處理上傳的檔案資料,並將每部分的資料封裝成到FileItem物件中
//在接收上傳檔案資料時,會將內容儲存到記憶體快取區中,如果檔案內容超過了 DiskFileItemFactory 指定的緩衝區的大小,
//那麼檔案將被儲存到磁碟上,儲存為DiskFileItemFactory指定目錄中的臨時檔案
//等檔案資料都接收完畢後,ServletFileUpload再從檔案中將資料寫入到上傳檔案目錄下的檔案中
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum size before a FileUploadException will be thrown
upload.setSizeMax(1000000* 100);
try {
//從test_upload.jsp中拿取資料,因為上傳頁的編碼格式跟一般的不同,使用的是enctype="multipart/form-data"
//form提交採用multipart/form-data,無法採用req.getParameter()取得資料
List fileItems =upload.parseRequest(req);
//迴圈提交的表單
for (Iterator iter = fileItems.iterator(); iter.hasNext();) {
FileItem item = (FileItem) iter.next();
String itemNo = "";
//判斷是檔案還是文字資訊
//是普通的表單輸入域
if(item.isFormField()) {
if ("itemNo".equals(item.getFieldName())) {
//將FileItem物件中儲存的主體內容作為一個字串返回,亂碼可以加編碼方式
itemNo = item.getString();
}
}
//是否為input="type"輸入域
if(!item.isFormField()){
//上傳檔案的名稱和完整路徑
String name =item.getName();
long size =item.getSize();
//判斷是否選擇了檔案
if ((name ==null || name.equals("")) && size==0) {
continue;
}
//擷取字串
name = name.substring(name.lastIndexOf("\\") + 1, name.length());
//將檔案儲存到目錄下,不修改檔名
item.write(new File(uploadPath, name));
//將圖片檔名寫入打資料庫
itemManager.uploadItemImage(itemNo, name);
}
}
resp.sendRedirect(req.getContextPath() + "/servlet/item/SearchItemServlet");
} catch (Exception e) {
e.printStackTrace();
throw new ApplicationException("上傳失敗!");
}
}
/**
* 在系統啟動的時候就初始化,在初始化時,檢查上傳圖片的資料夾和存放臨時檔案的資料夾,如果不存在就建立
*/
@Override
public void init() throws ServletException {
//獲取根目錄對應的真實物理路徑
uploadPath = new File(getServletContext().getRealPath("/upload"));
//如果目錄不存在
if (!uploadPath.exists()) {
//建立目錄
uploadPath.mkdir();
}
//臨時目錄
//File tempFile = new File(item.getName())構造臨時物件
tempPath = new File(getServletContext().getRealPath("/temp"));
if (!tempPath.exists()) {
tempPath.mkdir();
}
}
}
</span>
配置檔案:
<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>FileUploadServlet</servlet-name>
<servlet-class>uploadPack.FileUploadServlet</servlet-class>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/servlet/FileUploadServlet</url-pattern>
</servlet-mapping>
</web-app>
</span>
後面還會遇到很多其他上傳圖片的方法,會繼續總結整理。