重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要讲解了“Java中文件上传表单问题怎么处理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中文件上传表单问题怎么处理”吧!
创新互联建站专注于千山企业网站建设,响应式网站开发,成都做商城网站。千山网站建设公司,为千山等地区提供建站服务。全流程按需定制制作,专业设计,全程项目跟踪,创新互联建站专业和态度为您提供的服务
文件上傳處理是HTTP Web開發中較爲特殊的應用,對開發者有一定的要求。無論是流行的PHP,Aspx或者JSP都需要一定的處理技巧。由於實在想不起來10多年前是如何赤手純代碼來處理客貨混裝的HTML文件上傳表單,這次還是詳細地記錄一次,以備再過些時日忘卻了而備查。
還有一層考慮是,在處理HTML的文件上傳表單時,需要考慮與 GWA2Java的融合,涉及到GWA2 的文件處理的核心模塊,因此也需要或者也是檢視GWA2架構設計的一次極好的機會。
對此前的 GWA2 Java項目的巡視,我們發現已經有一些項目涉及到文件上傳,但基本上多數是使用Ajax異步上次等,回避了“客貨混裝”模式,某個HTML表單只負責文件上傳,而另外一個表單再收集其他數據。
所以,這次要在 GWA2Java 中更好的整合進文件上傳,并且是客貨混裝模式——處理一個表單,裏面同時包括兩個字段:張三的姓名文字和張三的頭像圖片。
1. 瀏覽器客戶端 HTML表單中enctype
如果需要在瀏覽器客戶端的HTML表單中進行文件上傳,需要明確顯式地指定 Form元素的 enctype 屬性為 multipart/form-data 。
2. 服務器端接收處理文件上傳的第三方組件
基於 Apache Tomcat的 Java Web Server,進行服務器端的文件上傳處理,推薦使用的組件是 Apache commons-fileupload-1.4.jar , 一并的也要引入 Apache commons-io-2.7.jar。
3. HTTP Request.getParameter 失效
儅客戶端使用文件上傳的表單遞交數據時,Java Web Server中常規的 Servlet 對象 HTTPRequest的主要方法 request.getParameter 就失效。這也是普通程序無法處理客貨混裝的原因之一。
取而代之的,儅 enctype=multipart/form-data , 需要通過第三方組件獲取到相應的表單參數。
在 GWA2 中,其中的路由模塊嚴重依賴HTTP Request的參數,這時候,需要將主要路由參數放入Form的Action屬性中。
可以改進的另外一個方法是,通過引入 Apache commons-fileupload 的相關對象,便利 FormItems 對象,從而獲得表單中的常規非文件字段,文本文件字段的名稱和值。
遍歷FormItems獲得HTTP Request請求參數之後,再通過 request.setAttribute寫回到當前Request對象,如此即可巧妙地彌補 request.getParameter 失效的問題。
由於在 GWA2Java 中,獲取外部參數通常由 Wht.get 的方法進行,這個方法除了調用 request.getParameter 之外,還會進一步地的訪問 request.getAttribute , 從而實現了對 request.setAttribute 的訪問。再進一步地的 Wht.get 還會對訪問數據做一些基本的安全檢查。
樣例代碼:
ServletFileUpload sfileupld = new ServletFileUpload((new DiskFileItemFactory()));
formItems = sfileupld.parseRequest(request); // can only be parsed once!
if (formItems != null && formItems.size() > 0){
String iname, ivalue; byte[] bytes;
for (FileItem item : formItems){
// processes only fields that are common form fields
if (item.isFormField()){
bytes = item.getFieldName().getBytes(“ISO-8859-1”); // why 8859?
iname = new String(bytes, “UTF-8”);
bytes = item.getString().getBytes(“ISO-8859-1”);
ivalue = new String(bytes, “UTF-8”);
request.setAttribute(iname, ivalue);
//debug(“ctrl/item: iname:”+iname+”, ivalue:”+ivalue);
}
}
}
4. HTML表單上傳request 能且僅能被parse一次
上文中提到的獲取 FormItems 需要從 HTTP Request中提取,
List
這裏的Request,只能被 parseRequest 執行一次,如果在同一次請求處理程序中,再次對這個 request 執行 parseRequest 時,就會返回異常為空的錯誤。
因此,儅我們需要在程序頂部通過便利 FormItems 設置 request.setAttribute 時,還需要保留 FormItems 作爲全局對象,在後面這裏處理實際上傳文件時使用,避免再次調用 parseRequest 產生爲空的錯誤異常。
5. 揮之不去的字符轉碼: 從 ISO-8859-1 到 UTF-8
從心裏上,我們是抗拒在代碼中進行字符集轉碼的,所以從一開始,我們在 GWA2Java 中進行了前後端統一全流程一貫地使用UTF-8字符集,從而避免在系統程序内做無謂的轉碼工作。(參考:-GWA2 Java版本的i18n/中文编码/乱码问题,https://ufqi.com/blog/gwa2-java-i18n/ )
偏偏這裏儅使用客貨混裝模式進行文件上傳時,通過parseRequest出來的 FormItem 其中的非ASCII字符的編碼是 ISO-8859-1 ,對於像 GWA2Java 這樣默認的 UTF-8 環境,字符集轉碼成爲迫不得已的事情。
6. 文件上傳處理方法的歸置
在 GWA2 的架構設計中,文件上傳功能,歸屬于文件模塊,引入系統的接口文件是 inc/FileA , 針對不同的文件系統,有不同的文件類來實現 inc/FileDirver , 如 默認的文件處理是 Linux 的 inc/FileSystem .
在歸屬上,這些 inc 目錄下的類及其方法是“大家閨秀”,一般不參與到具體業務處理程序的,只能通過統一界面接口 inc/WebApp 來調用。因此理想的是調用文件上傳的邏輯流程大致為:
ctrl/a.jsp –> mod/ModA –> inc/WebApp –> inc/FileA –> inc/FileSystem .
由於文件上傳,屬於非常規的“操作”需求,另外一種非標準的捷徑是,在 mod/ModA 中直接實例化 inc/FileSystem , 從而便利地觸發對 upload 方法的運用。但這只針對具體的項目可行,且不需要可移植性。比如如果宿主系統不是 Linux, 那就不能實例化 inc/FileSystem , 相應地可能需要實例化 inc/WindowsFileSystem 來處理宿主環境是 Windows 的文件上傳。
7. 有進有出,文件刪除的操作
在此之前,核心接口類 inc/WebApp 中定義了 readObject/writeObject 用來讀寫非數據庫源的數據。其中 inc/FileA 中相應地定義了 read/write 方法,只是還沒有對應的刪除方法 rm 的實現。
接著這個機會,我們歸置並實現了 inc/FileA, inc/FileDriver 和 inc/FileSystem 三個類的 rm 方法,同時改造 inc/WebApp.rmBy 方法,將上述方法進行對接。
inc/WebApp.rmBy(“file:Path_To_File”) –> inc/FileA.rm –> inc/FileSystem.rm .
GWA2Java, GWA2 就是這樣通過一個又一個項目實踐,不斷豐富完善,日益健壯强大,儅融合和沉澱足夠多的智慧和精華,一定能取得更大的成就。我們在 UfqiWork 有福工坊 ( https://ufqi.com/work/ )上首先實現了 GWA2Java 處理文件上傳的客貨混裝模式。
感谢各位的阅读,以上就是“Java中文件上传表单问题怎么处理”的内容了,经过本文的学习后,相信大家对Java中文件上传表单问题怎么处理这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!