Java 項目中,當需要高性能上傳文件時,往往就需要依靠組件,而不是手寫的servlet了,一般的選擇包括jakarta commons-fileupload以及smartupload,由於後者在上傳大文件時往往會出錯,另外對中文支持一般,筆者采用了前者。(這一點法老深有體會!)
筆者寫了一個名為Fileupload的類,用來封裝上傳動作。
文件選擇頁面代碼:
<script language="JavaScript" type="text/JavaScript"> function check(){ if(document.Form1.checkbox[0].checked == true){ document.Form1.ch1.value = document.Form1.checkbox[0].value; } if(document.Form1.checkbox[1].checked == true){ document.Form1.ch2.value = document.Form1.checkbox[1].value; } var newAction = "11"; newAction = Form1.action + "?ch1=" + document.Form1.ch1.value + "&ch2=" + document.Form1.ch2.value; //更新action,使得後面通過頁面url獲取參數 Form1.action = newAction; } </script> <Html> <head> <title>Excel文件上載</title></head> <body bgcolor="#FFFFFF" text="#000000"><p><font size="5"color="#FF0000"> <b>Excel文件上載</b></font></p> <p>文件上傳 目的地選擇</p> <form name="Form1" onSubmit="return check()" enctype="multipart/form-data" method="post" action="uploadResult.JSP"> <input type="checkbox" name="checkbox" value="ch1">公共文件夾 <input type="hidden" name="ch1" class="input" id="ch1" size="20"> <input type="checkbox" name="checkbox" value="ch2">測試文件夾 <input type="hidden" name="ch2" class="input" id="ch2" size="20"> <p>選擇Excel文件 <input type="file" name="File1" size="20" maxlength="20"> </p> <p>注意:請確保選中的為Excel格式文件,Excel文件名不能包含空格,文件重名自動覆蓋</p> <p> <input type="submit"value="提交"> <input type="reset" value="取消"> </p> </form>
處理頁面代碼:
<% String temp = "C:\TEMP"; char[] label = new char[2]; String labelString = ""; for(int i = 0; i < label.length; i++){ label[i] = '0'; } String des = request.getRealPath("/FinancialReports/ExcelFile"); //通過檢測checkbox的選擇情況,確定文件上傳路徑 //假設上傳路徑構成為serverPath + 2位標示符 + 具體文件名 if(request.getParameterValues("ch1") != null){ String[] ch1 = request.getParameterValues("ch1"); if(ch1[0].equals("ch1")){ System.out.println("ch1 checked..."); //添加文件標示 label[0] = '1'; } } if(request.getParameterValues("ch2") != null){ String[] ch2 = request.getParameterValues("ch2"); if(ch2[0].equals("ch2")){ System.out.println("ch2 checked..."); //添加文件標示 label[1] = '1'; } } for(int i = 0; i < label.length; i++){ labelString = labelString + label[i]; } des = des + "\" + labelString; System.out.println("Hello World: " + des); Fileupload fileUpload = new Fileupload(temp, des, request); boolean uploadResult = fileUpload.Upload(true); %>
Fileupload封裝類:
/* * Author: Huang ye(www.hyweb.Net) * 代碼開源, 引用請注明出處 * * 2005-11-8 * */ package net.hyweb; import java.io.File; import Java.util.*; import org.apache.commons.fileupload.*; import Javax.servlet.http.HttpServletRequest; /** * @author Huangye * * TODO 要更改此生成的類型注釋的模板,請轉至 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板 */ public class Fileupload { //當上傳文件超過限制時設定的臨時文件位置 private String tempPath = "C:\TEMP"; //文件上傳目標目錄 private String destinationPath; //獲取的上傳請求 private HttpServletRequest fileuploadRequest = null; //設置最多只允許在內存中存儲的數據,單位:字節 private int sizeThreshold = 4096; //設置允許用戶上傳文件大小,單位:字節 //共10M private long sizeMax = 10485760; public Fileupload(){ } public Fileupload(String tempPath, String destinationPath){ this.tempPath = tempPath; this.destinationPath = destinationPath; } public Fileupload(String tempPath, String destinationPath, HttpServletRequest fileuploadRequest){ this.tempPath = tempPath; this.destinationPath = destinationPath; this.fileuploadRequest = fileuploadRequest; } /** 文件上載 * @return true —— success; false —— fail. */ public boolean Upload(){ //如果沒有臨時目錄,則創建它 if(!(new File(tempPath).isDirectory())){ try{ new File(tempPath).mkdirs(); }catch(SecurityException e){ System.out.println("can not make security direcoty"); } } //如果沒有上傳目的目錄,則創建它 if(!(new File(destinationPath).isDirectory())){ try{ new File(destinationPath).mkdirs(); }catch(SecurityException e){ System.out.println("can not make security direcoty"); } } //上傳項目只要足夠小,就應該保留在內存裡。 //較大的項目應該被寫在硬盤的臨時文件上。 //非常大的上傳請求應該避免。 //限制項目在內存中所占的空間,限制最大的上傳請求,並且設定臨時文件的位置。 DiskFileUpload fu = new DiskFileUpload(); //設置最多只允許在內存中存儲的數據,單位:字節 fu.setSizeThreshold(sizeThreshold); //設置允許用戶上傳文件大小,單位:字節 //10M fu.setSizeMax(sizeMax); //設置一旦文件大小超過getSizeThreshold()的值時數據存放在硬盤的目錄 fu.setRepositoryPath(tempPath); Iterator iter = null; //讀取上傳信息 try { List fileItems = fu.parseRequest(fileuploadRequest); //處理上傳項目 //依次處理每個上傳的文件 iter = fileItems.iterator(); } catch (FileUploadException e) { e.printStackTrace(); return false; } while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); //忽略其他不是文件域的所有表單信息 if (!item.isFormFIEld()) { //上傳的是文件信息 String fIEldName = item.getFIEldName(); String name = item.getName(); if((name == null) || name.equals("") && item.getSize() == 0){ continue; } System.out.println("processUploadedFile: " + name + " ; " + fIEldName); String value = item.getString(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); String fileName = this.GetFileName(name); try { item.write(new File(this.destinationPath + fileName)); } catch (Exception e) { e.printStackTrace(); return false; } }else{ //上傳的是普通表單字域 String fIEldName = item.getFIEldName(); String name = item.getName(); if((name == null) || name.equals("") && item.getSize() == 0){ continue; } String value = item.getString(); } } return true; } /**從路徑中獲取單獨文件名 * @author Huangye * * TODO 要更改此生成的類型注釋的模板,請轉至 * 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板 */ public String GetFileName(String filepath) { String returnstr = "*.*"; int length = filepath.trim().length(); filepath = filepath.replace('\', '/'); if(length >0) { int i = filepath.lastIndexOf("/"); if (i >= 0) { filepath = filepath.substring(i + 1); returnstr = filepath; } } return returnstr; } /** * 省略所有的getXXX和setXXX訪問器方法 */ }