Servlet 文件上傳
Servlet 可以與 HTML form 標(biāo)簽一起使用,來(lái)允許用戶上傳文件到服務(wù)器。上傳的文件可以是文本文件或圖像文件或任何文檔。
創(chuàng)建一個(gè)文件上傳表單
下面的 HTML 代碼創(chuàng)建了一個(gè)文件上傳表單。以下幾點(diǎn)需要注意:
表單 method 屬性應(yīng)該設(shè)置為 POST 方法,不能使用 GET 方法。
表單 enctype 屬性應(yīng)該設(shè)置為 multipart/form-data.
表單 action 屬性應(yīng)該設(shè)置為在后端服務(wù)器上處理文件上傳的 Servlet 文件。下面的實(shí)例使用了 UploadServlet Servlet 來(lái)上傳文件。
上傳單個(gè)文件,您應(yīng)該使用單個(gè)帶有屬性 type="file" 的 <input .../> 標(biāo)簽。為了允許多個(gè)文件上傳,請(qǐng)包含多個(gè) name 屬性值不同的 input 標(biāo)簽。輸入標(biāo)簽具有不同的名稱屬性的值。瀏覽器會(huì)為每個(gè) input 標(biāo)簽關(guān)聯(lián)一個(gè)瀏覽按鈕。
<html> <head> <title>文件上傳表單</title> </head> <body> <h3>文件上傳:</h3> 請(qǐng)選擇要上傳的文件:<br /> <form action="UploadServlet" method="post" enctype="multipart/form-data"> <input type="file" name="file" size="50" /> <br /> <input type="submit" value="上傳文件" /> </form> </body> </html>
這將顯示下面的結(jié)果,允許用戶從本地計(jì)算機(jī)選擇一個(gè)文件,當(dāng)用戶點(diǎn)擊"上傳文件"時(shí),表單會(huì)連同從本地計(jì)算機(jī)選擇的文件一起提交:
<b>文件上傳:</b> 請(qǐng)選擇要上傳的文件:<br /> <input type="file" name="file" size="50" /> <br /> <input type="button" value="上傳文件" /> <br /> 注:這只是虛擬的表單,不會(huì)正常工作。
編寫(xiě)后臺(tái) Servlet
以下是 Servlet UploadServlet,會(huì)接受上傳的文件,并把它儲(chǔ)存在目錄 <Tomcat-installation-directory>/webapps/data 中。這個(gè)目錄名也可以使用外部配置來(lái)添加,比如 web.xml 中的 context-param 元素,如下所示:
<web-app> .... <context-param> <description>Location to store uploaded file</description> <param-name>file-upload</param-name> <param-value> c:\apache-tomcat-5.5.29\webapps\data\ </param-value> </context-param> .... </web-app>
以下是 UploadServlet 的源代碼,可以一次處理多個(gè)文件的上傳。在繼續(xù)操作之前,請(qǐng)確認(rèn)下列各項(xiàng):
下面的實(shí)例依賴于 FileUpload,所以一定要確保在您的 classpath 中有最新版本的 commons-fileupload.x.x.jar 文件。可以從 http://commons.apache.org/fileupload/ 下載。
FileUpload 依賴于 Commons IO,所以一定要確保在您的 classpath 中有最新版本的 commons-io-x.x.jar 文件??梢詮?http://commons.apache.org/io/ 下載。
在測(cè)試下面實(shí)例時(shí),您上傳的文件大小不能大于 maxFileSize,否則文件將無(wú)法上傳。
請(qǐng)確保已經(jīng)提前創(chuàng)建好目錄 c:\temp and c:\apache-tomcat-5.5.29\webapps\data。
// 導(dǎo)入必需的 java 庫(kù) import java.io.*; import java.util.*; import javax.servlet.ServletConfig; 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; import org.apache.commons.io.output.*; public class UploadServlet extends HttpServlet { private boolean isMultipart; private String filePath; private int maxFileSize = 50 * 1024; private int maxMemSize = 4 * 1024; private File file ; public void init( ){ // 獲取文件將被存儲(chǔ)的位置 filePath = getServletContext().getInitParameter("file-upload"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { // 檢查我們有一個(gè)文件上傳請(qǐng)求 isMultipart = ServletFileUpload.isMultipartContent(request); response.setContentType("text/html"); java.io.PrintWriter out = response.getWriter( ); if( !isMultipart ){ out.println("<html>"); out.println("<head>"); out.println("<title>Servlet upload</title>"); out.println("</head>"); out.println("<body>"); out.println("<p>No file uploaded</p>"); out.println("</body>"); out.println("</html>"); return; } DiskFileItemFactory factory = new DiskFileItemFactory(); // 文件大小的最大值將被存儲(chǔ)在內(nèi)存中 factory.setSizeThreshold(maxMemSize); // Location to save data that is larger than maxMemSize. factory.setRepository(new File("c:\\temp")); // 創(chuàng)建一個(gè)新的文件上傳處理程序 ServletFileUpload upload = new ServletFileUpload(factory); // 允許上傳的文件大小的最大值 upload.setSizeMax( maxFileSize ); try{ // 解析請(qǐng)求,獲取文件項(xiàng) List fileItems = upload.parseRequest(request); // 處理上傳的文件項(xiàng) Iterator i = fileItems.iterator(); out.println("<html>"); out.println("<head>"); out.println("<title>Servlet upload</title>"); out.println("</head>"); out.println("<body>"); while ( i.hasNext () ) { FileItem fi = (FileItem)i.next(); if ( !fi.isFormField () ) { // 獲取上傳文件的參數(shù) String fieldName = fi.getFieldName(); String fileName = fi.getName(); String contentType = fi.getContentType(); boolean isInMemory = fi.isInMemory(); long sizeInBytes = fi.getSize(); // 寫(xiě)入文件 if( fileName.lastIndexOf("\\") >= 0 ){ file = new File( filePath + fileName.substring( fileName.lastIndexOf("\\"))) ; }else{ file = new File( filePath + fileName.substring(fileName.lastIndexOf("\\")+1)) ; } fi.write( file ) ; out.println("Uploaded Filename: " + fileName + "<br>"); } } out.println("</body>"); out.println("</html>"); }catch(Exception ex) { System.out.println(ex); } } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { throw new ServletException("GET method used with " + getClass( ).getName( )+": POST method required."); } }
編譯和運(yùn)行 Servlet
編譯上面的 Servlet UploadServlet,并在 web.xml 文件中創(chuàng)建所需的條目,如下所示:
<servlet> <servlet-name>UploadServlet</servlet-name> <servlet-class>UploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/UploadServlet</url-pattern> </servlet-mapping>
現(xiàn)在嘗試使用您在上面創(chuàng)建的 HTML 表單來(lái)上傳文件。當(dāng)您在瀏覽器中訪問(wèn):http://localhost:8080/UploadFile.htm 時(shí),它會(huì)顯示下面的結(jié)果,這將有助于您從本地計(jì)算機(jī)上傳任何文件。
<b>文件上傳:</b> 請(qǐng)選擇要上傳的文件:<br /> <input type="file" name="file" size="50" /> <br /> <input type="button" value="上傳文件" />
如果您的 Servelt 腳本能正常工作,那么您的文件會(huì)被上傳到 c:\apache-tomcat-5.5.29\webapps\data\ 目錄中。