隨筆-17  評論-64  文章-79  trackbacks-1
          這個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 飛鳥 閱讀(411) 評論(1)  編輯  收藏 所屬分類: JAVA

          評論:
          # re: java上傳 2008-09-14 23:47 | cauchy
          GOOD  回復  更多評論
            
          主站蜘蛛池模板: 乐业县| 嘉黎县| 山丹县| 龙江县| 肥乡县| 永福县| 灵寿县| 博罗县| 广河县| 桓仁| 隆林| 宣武区| 嘉义县| 南开区| 静乐县| 航空| 台南市| 岗巴县| 涟源市| 金乡县| 虞城县| 赤峰市| 元朗区| 高安市| 琼中| 嘉兴市| 四平市| 陵川县| 玉林市| 伽师县| 临沭县| 会理县| 七台河市| 巨鹿县| 洪江市| 麦盖提县| 依安县| 大冶市| 武汉市| 城口县| 南充市|