這個Upload比smartUpload好用多了.完全是我一個個byte調試出來的,不象smartUpload的bug具多.
調用方法:
Upload?up?=?new?Upload();
up.init(request);
/**
此處可以調用setSaveDir(String?saveDir);設置保存路徑
調用setMaxFileSize(long?size)設置上傳文件的最大字節.
調用setTagFileName(String)設置上傳后文件的名字(只對第一個文件有效)
*/
up.?uploadFile();
然后String[]?names?=?up.getFileName();得到上傳的文件名,文件絕對路徑應該是
保存的目錄saveDir+"/"+names[i];
可以通過up.getParameter("field");得到上傳的文本或up.getParameterValues("filed")
得到同名字段如多個checkBox的值.
其它的自己試試.
源碼:____________________________________________________________
package?com.inmsg.beans;
import?java.io.*;
import?java.util.*;
import?javax.servlet.*;
import?javax.servlet.http.*;
public?class?Upload?{
??private?String?saveDir?=?".";?//要保存文件的路徑
??private?String?contentType?=?"";?//文檔類型
??private?String?charset?=?"";?//字符集
??private?ArrayList?tmpFileName?=?new?ArrayList();?//臨時存放文件名的數據結構
??private?Hashtable?parameter?=?new?Hashtable();?//存放參數名和值的數據結構
??private?ServletContext?context;?//程序上下文,用于初始化
??private?HttpServletRequest?request;?//用于傳入請求對象的實例
??private?String?boundary?=?"";?//內存數據的分隔符
??private?int?len?=?0;?//每次從內在中實際讀到的字節長度
??private?String?queryString;
??private?int?count;?//上載的文件總數
??private?String[]?fileName;?//上載的文件名數組
??private?long?maxFileSize?=?1024?*?1024?*?10;?//最大文件上載字節;
??private?String?tagFileName?=?"";
??public?final?void?init(HttpServletRequest?request)?throws?ServletException?{
????this.request?=?request;
????boundary?=?request.getContentType().substring(30);?//得到內存中數據分界符
????queryString?=?request.getQueryString();
??}
??public?String?getParameter(String?s)?{?//用于得到指定字段的參數值,重寫request.getParameter(String?s)
????if?(parameter.isEmpty())?{
??????return?null;
????}
????return?(String)?parameter.get(s);
??}
??public?String[]?getParameterValues(String?s)?{?//用于得到指定同名字段的參數數組,重寫request.getParameterValues(String?s)
????ArrayList?al?=?new?ArrayList();
????if?(parameter.isEmpty())?{
??????return?null;
????}
????Enumeration?e?=?parameter.keys();
????while?(e.hasMoreElements())?{
??????String?key?=?(String)?e.nextElement();
??????if?(?-1?!=?key.indexOf(s?+?"||||||||||")?||?key.equals(s))?{
????????al.add(parameter.get(key));
??????}
????}
????if?(al.size()?==?0)?{
??????return?null;
????}
????String[]?value?=?new?String[al.size()];
????for?(int?i?=?0;?i?<?value.length;?i++)?{
??????value[i]?=?(String)?al.get(i);
????}
????return?value;
??}
??public?String?getQueryString()?{
????return?queryString;
??}
??public?int?getCount()?{
????return?count;
??}
??public?String[]?getFileName()?{
????return?fileName;
??}
??public?void?setMaxFileSize(long?size)?{
????maxFileSize?=?size;
??}
??public?void?setTagFileName(String?filename)?{
????tagFileName?=?filename;
??}
??public?void?setSaveDir(String?saveDir)?{?//設置上載文件要保存的路徑
????this.saveDir?=?saveDir;
????File?testdir?=?new?File(saveDir);?//為了保證目錄存在,如果沒有則新建該目錄
????if?(!testdir.exists())?{
??????testdir.mkdirs();
????}
??}
??public?void?setCharset(String?charset)?{?//設置字符集
????this.charset?=?charset;
??}
??public?boolean?uploadFile()?throws?ServletException,?IOException?{?//用戶調用的上載方法
????setCharset(request.getCharacterEncoding());
????return?uploadFile(request.getInputStream());
??}
??private?boolean?uploadFile(ServletInputStream?servletinputstream)?throws?//取得央存數據的主方法
??????ServletException,?IOException?{
????String?line?=?null;
????byte[]?buffer?=?new?byte[256];
????while?(?(line?=?readLine(buffer,?servletinputstream,?charset))?!=?null)?{
??????if?(line.startsWith("Content-Disposition:?form-data;"))?{
????????int?i?=?line.indexOf("filename=");
????????if?(i?>=?0)?{?//如果一段分界符內的描述中有filename=,說明是文件的編碼內容
??????????String?fName?=?getFileName(line);
??????????if?(fName.equals(""))?{
????????????continue;
??????????}
??????????if?(count?==?0?&&?tagFileName.length()?!=?0)?{
????????????String?ext?=?fName.substring(?(fName.lastIndexOf(".")?+?1));
????????????fName?=?tagFileName?+?"."?+?ext;
??????????}
??????????tmpFileName.add(fName);
??????????count++;
??????????while?(?(line?=?readLine(buffer,?servletinputstream,?charset))?!=?null)?{
????????????if?(line.length()?<=?2)?{
??????????????break;
????????????}
??????????}
??????????File?f?=?new?File(saveDir,?fName);
??????????FileOutputStream?dos?=?new?FileOutputStream(f);
??????????long?size?=?0l;
??????????while?(?(line?=?readLine(buffer,?servletinputstream,?null))?!=?null)?{
????????????if?(line.indexOf(boundary)?!=?-1)?{
??????????????break;
????????????}
????????????size?+=?len;
????????????if?(size?>?maxFileSize)?{
??????????????throw?new?IOException("文件超過"?+?maxFileSize?+?"字節!");
????????????}
????????????dos.write(buffer,?0,?len);
??????????}
??????????dos.close();
????????}
????????else?{?//否則是字段編碼的內容
??????????String?key?=?getKey(line);
??????????String?value?=?"";
??????????while?(?(line?=?readLine(buffer,?servletinputstream,?charset))?!=?null)?{
????????????if?(line.length()?<=?2)?{
??????????????break;
????????????}
??????????}
??????????while?(?(line?=?readLine(buffer,?servletinputstream,?charset))?!=?null)?{
????????????if?(line.indexOf(boundary)?!=?-1)?{
??????????????break;
????????????}
????????????value?+=?line;
??????????}
??????????put(key,?value.trim(),?parameter);
????????}
??????}
????}
????if?(queryString?!=?null)?{
??????String[]?each?=?split(queryString,?"&");
??????for?(int?k?=?0;?k?<?each.length;?k++)?{
????????String[]?nv?=?split(each[k],?"=");
????????if?(nv.length?==?2)?{
??????????put(nv[0],?nv[1],?parameter);
????????}
??????}
????}
????fileName?=?new?String[tmpFileName.size()];
????for?(int?k?=?0;?k?<?fileName.length;?k++)?{
??????fileName[k]?=?(String)?tmpFileName.get(k);?//把ArrayList中臨時文件名倒入數據中供用戶調用
????}
????if?(fileName.length?==?0)?{
??????return?false;?//如果fileName數據為空說明沒有上載任何文件
????}
????return?true;
??}
??private?void?put(String?key,?String?value,?Hashtable?ht)?{
????if?(!ht.containsKey(key))?{
??????ht.put(key,?value);
????}
????else?{?//如果已經有了同名的KEY,就要把當前的key更名,同時要注意不能構成和KEY同名
??????try?{
????????Thread.currentThread().sleep(1);?//為了不在同一ms中產生兩個相同的key
??????}
??????catch?(Exception?e)?{}
??????key?+=?"||||||||||"?+?System.currentTimeMillis();
??????ht.put(key,?value);
????}
??}
??/*
???調用ServletInputstream.readLine(byte[]?b,int?offset,length)方法,該方法是從ServletInputstream流中讀一行
???到指定的byte數組,為了保證能夠容納一行,該byte[]b不應該小于256,重寫的readLine中,調用了一個成員變量len為
???實際讀到的字節數(有的行不滿256),則在文件內容寫入時應該從byte數組中寫入這個len長度的字節而不是整個byte[]
???的長度,但重寫的這個方法返回的是String以便分析實際內容,不能返回len,所以把len設為成員變量,在每次讀操作時
???把實際長度賦給它.
???也就是說在處理到文件的內容時數據既要以String形式返回以便分析開始和結束標記,又要同時以byte[]的形式寫到文件
???輸出流中.
???*/
??private?String?readLine(byte[]?Linebyte,
??????????????????????????ServletInputStream?servletinputstream,?String?charset)?{
????try?{
??????len?=?servletinputstream.readLine(Linebyte,?0,?Linebyte.length);
??????if?(len?==?-1)?{
????????return?null;
??????}
??????if?(charset?==?null)?{
????????return?new?String(Linebyte,?0,?len);
??????}
??????else?{
????????return?new?String(Linebyte,?0,?len,?charset);
??????}
????}
????catch?(Exception?_ex)?{
??????return?null;
????}
??}
??private?String?getFileName(String?line)?{?//從描述字符串中分離出文件名
????if?(line?==?null)?{
??????return?"";
????}
????int?i?=?line.indexOf("filename=");
????line?=?line.substring(i?+?9).trim();
????i?=?line.lastIndexOf("\\");
????if?(i?<?0?||?i?>=?line.length()?-?1)?{
??????i?=?line.lastIndexOf("/");
??????if?(line.equals("\"\""))?{
????????return?"";
??????}
??????if?(i?<?0?||?i?>=?line.length()?-?1)?{
????????return?line;
??????}
????}
????return?line.substring(i?+?1,?line.length()?-?1);
??}
??private?String?getKey(String?line)?{?//從描述字符串中分離出字段名
????if?(line?==?null)?{
??????return?"";
????}
????int?i?=?line.indexOf("name=");
????line?=?line.substring(i?+?5).trim();
????return?line.substring(1,?line.length()?-?1);
??}
??public?static?String[]?split(String?strOb,?String?mark)?{
????if?(strOb?==?null)?{
??????return?null;
????}
????StringTokenizer?st?=?new?StringTokenizer(strOb,?mark);
????ArrayList?tmp?=?new?ArrayList();
????while?(st.hasMoreTokens())?{
??????tmp.add(st.nextToken());
????}
????String[]?strArr?=?new?String[tmp.size()];
????for?(int?i?=?0;?i?<?tmp.size();?i++)?{
??????strArr[i]?=?(String)?tmp.get(i);
????}
????return?strArr;
??}
}
下載其實非常簡單,只要如下處理,就不會發生問題。
??public?void?downLoad(String?filePath,HttpServletResponse?response,boolean?isOnLine)
??throws?Exception{
????File?f?=?new?File(filePath);
????if(!f.exists()){
??????response.sendError(404,"File?not?found!");
??????return;
????}
????BufferedInputStream?br?=?new?BufferedInputStream(new?FileInputStream(f));
????byte[]?buf?=?new?byte[1024];
????int?len?=?0;
????
????response.reset();????????????????????????????????????????????//非常重要
????if(isOnLine){????????????????????????????????????????????????//在線打開方式
??????URL?u?=?new?URL("file:///"+filePath);
??????response.setContentType(u.openConnection().getContentType());
??????response.setHeader("Content-Disposition",?"inline;?filename="+f.getName());
?????????????????????????????????????????????????????????????????//文件名應該編碼成UTF-8
????}
????else{????????????????????????????????????????????????????????//純下載方式
??????response.setContentType("application/x-msdownload");?
??????response.setHeader("Content-Disposition",?"attachment;?filename="?+?f.getName());?
????}
????OutputStream?out?=?response.getOutputStream();
????while((len?=?br.read(buf))?>0)
??????out.write(buf,0,len);
????br.close();
????out.close();
??}?
posted on 2006-07-11 16:25
飛鳥 閱讀(399)
評論(1) 編輯 收藏 所屬分類:
JAVA