近期項目要用到文件上傳功能, 先試了用 Jsp Smart upload, 結果發現一個問題: 如果上傳的文件名中有漢字, 則發生無法讀取參數和文件數據的錯誤. 后來想到 Struts 的文件上傳功能在 Tomcat 和 Weblogic 下都沒有問題, 就想到用它來做上傳功能, 于是到 Apache 網站下載了 Commons FileUpload 看了看, 發現雖然功能都用, 但是使用太不方便, 例如獲取表單參數竟然要一個一個的遍歷, 于是就動手寫了一個封裝類, 這個類可以方便的讀取表單參數和文件項目.
首先說一下參考資料:
FileUpload 主站點:
http://jakarta.apache.org/commons/fileupload/index.html
下載 FileUpload 的源碼:
http://archive.apache.org/dist/jakarta/commons/fileupload/source/
點擊 commons-fileupload-1.0-src.zip 下載源碼.
下載 FileUpload 的二進制包(JAR文件):
http://archive.apache.org/dist/jakarta/commons/fileupload/binaries/
在列表中點擊 commons-fileupload-1.0.zip 26-Jun-2003 08:32 128K,
下載后解壓縮得到的 commons-fileupload-1.0.jar 就可以放到類路徑中使用了.
Apache 自己的使用指導(英文版), 強烈建議如果要深入了解如何使用的人看看這個網頁:
http://jakarta.apache.org/commons/fileupload/using.html
下面就是這個類的源碼了(已經在源碼注釋中包含了使用說明了):
1 package studio.beansoft.jsp;
2 import java.util.*;
3 import java.io.*;
4 import javax.servlet.http.*;
5 import org.apache.commons.fileupload.*;
6 /**
7 * Jakarta commons FileUpload 封裝類.
8 * 提供: 參數讀取(在 Tomcat 4, 5 下測試過似乎沒有中文問題), 文件保存功能.
9 *
10 * NOTE: 所有的表單和頁面編碼都是按照 UTF-8 來處理的.
11 * TODO Refactor to make encoding configable.
12 *
13 * 示例代碼(在 JSP 頁面中, 忽略了異常處理代碼):
14 * test.htm
15 <form action="test.jsp">
16 Input name: <input type="text" name="username"><br>
17 Select a file: <input type="file" name="file1"><br>
18 <input type="submit" value="Upload">
19 </form>
20 test.jsp
21 <%@ page contentType="text/html;charset=utf8" %>
22 <%@ page import="studio.beansoft.jsp.*, java.io.*" %>
23 <%
24 JakartaFileUploadHandler uploadHandler = new JakartaFileUploadHandler(request);
25 // 如果是文件上傳表單
26 if(uploadHandler.isMultipart()) {
27 // 讀取參數
28 String parameterValue = uploadHandler.getParameter("username");
29 out.println("username=" + parameterValue);
30 // 保存文件
31 JakartaFileUploadHandler.saveFileItem(uploadHandler.getFileItem("file1"), new File("file1.txt"));
32 }
33 %>
34 更多參考資料請看 Apache 的網站上的指導文章:
35 Using FileUpload
36 @link http://jakarta.apache.org/commons/fileupload/using.html
37 *
38 * @see #getParameter(String)
39 * @see #getParameterValues(String)
40 * @see #saveFileItem(FileItem, File)
41 *
42 * 這個類依賴于 Jakarta commons-fileupload-1.0.zip.
43 *
44 * @author beansoft beansoftstudio@msn.com
45 * @version 1.01
46 * 2005-11-30
47 */
48 public class JakartaFileUploadHandler
49 {
50 /** 文件域列表 */
51 private Map fileFields= new TreeMap();
52 /** 表單域列表 */
53 private Map formFields= new TreeMap();
54 /** Check that we have a file upload request */
55 private boolean isMultipart = false;
56 private HttpServletRequest request = null;
57 /**
58 * 空構造器.
59 */
60 public JakartaFileUploadHandler() {
61 }
62 /**
63 * 根據現有參數構造一個上傳處理器.
64 */
65 public JakartaFileUploadHandler(HttpServletRequest request) {
66 setRequest(request);
67 }
68 /**
69 * 設置 HttpServletRequest 并分析里面的表單數據.
70 * @param request - HttpServletRequest
71 */
72 public void setRequest(HttpServletRequest request) {
73 this.request = request;
74 isMultipart = FileUpload.isMultipartContent(request);
75 // 如果是文件上傳請求, 就提取里面的參數
76 if(isMultipart) {
77 // Create a new file upload handler
78 DiskFileUpload upload = new DiskFileUpload();
79 /*
80 * Nov 29 2005, set default upload encoding to UTF-8.
81 * Specifies the character encoding to be used when reading the headers of
82 * individual parts. When not specified, or <code>null</code>, the platform
83 * default encoding is used.
84 */
85 upload.setHeaderEncoding("UTF-8");
86 try {
87 // Parse the request
88 List /* FileItem */ items = upload.parseRequest(request);
89 // Process the uploaded items
90 Iterator iter = items.iterator();
91 while (iter.hasNext()) {
92 FileItem item = (FileItem) iter.next();
93 String name = item.getFieldName();
94 String value = item.getString();
95 if (item.isFormField()) {
96 processFormField(item);
97 } else {
98 processUploadedFile(item);
99 }
100 }
101 } catch (Exception ex) {
102 System.err.println("無法處理上傳數據:" + ex);
103 }
104 }
105 }
106 /**
107 * 處理表單項目.
108 * @param item - FileItem 對象
109 */
110 private void processFormField(FileItem item) {
111 String name = item.getFieldName();
112 // NOTE 文件上傳統一使用 UTF-8 編碼 2005-10-16
113 String value = null;
114 try {
115 value = item.getString("UTF-8");
116 } catch (UnsupportedEncodingException e) {
117 }
118 // 首先嘗試獲取原來的值
119 Object oldValue = formFields.get(name);
120 if(oldValue == null) {
121 formFields.put(name, value);
122 } else {
123 // 多個值存儲為 List
124 // 原來為單個值則添加現有的值
125 try {
126 String oldString = (String)oldValue;
127 List list = new ArrayList();
128 list.add(oldString);
129 list.add(value);
130 formFields.put(name, list);
131 } catch (Exception ex) {
132 // ex.printStackTrace();
133 }
134 // 原來為多個值則添加現有的值
135 try {
136 List list = (List)oldValue;
137 list.add(value);
138 formFields.put(name, list);
139 } catch (Exception ex) {
140 // ex.printStackTrace();
141 }
142 }
143 }
144 /**
145 * 處理文件項目.
146 * @param item - FileItem 對象
147 */
148 private void processUploadedFile(FileItem item) {
149 String name = item.getFieldName();
150 fileFields.put(name, item);
151 }
152 /**
153 * 獲取上傳的文件項目.
154 * @param name - String, 文件域名稱
155 * @return FileItem - org.apache.commons.fileupload.FileItem 對象
156 */
157 public FileItem getFileItem(String name) {
158 if(!isMultipart) return null;
159 return (FileItem) (fileFields.get(name));
160 }
161 /**
162 * 獲取表單參數.
163 * @param name - String, 表單域名稱
164 * @return String - 表單域值
165 */
166 public String getParameter(String name) {
167 if(!isMultipart) {
168 return request.getParameter(name);
169 }
170 Object value = formFields.get(name);
171 if(value != null) {
172 if(value instanceof String) {
173 return (String)value;
174 }
175 }
176 return null;
177 }
178 /**
179 * 獲取表單域的多個參數值.
180 * @param name - String, 表單域名稱
181 * @return String[] - 表單域的多個取值
182 */
183 public String[] getParameterValues(String name) {
184 if(!isMultipart) {
185 return request.getParameterValues(name);
186 }
187 Object value = formFields.get(name);
188 if(value != null) {
189 if(value instanceof List) {
190 return (String[]) ((List)value).toArray(new String[0]);
191 }
192 }
193 return null;
194 }
195 /**
196 * 返回當前請求是否為多部分上傳請求.
197 */
198 public boolean isMultipart()
199 {
200 return isMultipart;
201 }
202 /**
203 * 保存 FileItem 對象到指定的文件.
204 * @param item - FileItem, 要保存的上傳文件項目
205 * @param file - File, 要保存到的文件對象
206 * @return boolean - 是否保存成功
207 */
208 public static boolean saveFileItem(FileItem item, File file) {
209 try {
210 item.write(file);
211 return true;
212 } catch (Exception ex) {
213 // ex.printStackTrace();
214 System.out.println("saveFileItem error:" + ex);
215 }
216 return false;
217 }
218 /**
219 * 獲取 FileItem 對象的輸入流.
220 * @param item - FileItem, 要獲取輸入流的上傳文件對象
221 * @return InputStream - 對象的輸入流
222 */
223 public static InputStream getInputStreamFromFileItem(FileItem item) {
224 try {
225 return item.getInputStream();
226 } catch (Exception ex) {
227 // ex.printStackTrace();
228 }
229 return null;
230 }
231 }
232
本文轉自
http://beansoft.java-cn.org/Wiki.jsp?page=JakartaFileUploadHandler,收藏參考學習。
posted on 2007-08-09 09:44
Scott.Pan 閱讀(1009)
評論(0) 編輯 收藏 所屬分類:
代碼收藏夾