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訪問器方法
*/
}