本來在介紹 用TOMCAT作簡單的jsp web開發(fā) 的帖子中已經(jīng)提過,但是有些筒子不喜歡看又臭又硬的文字,所以可能不會注意到,就重新開帖發(fā)出來。請其他管理見諒。
順便打算今后多寫幾個util函數(shù),能用上的就用下。代碼開發(fā)的過程見 用TOMCAT作簡單的jsp web開發(fā)
剛才和lp看完電影,把jsp頁面抽出class調(diào)整了一下。最近總上經(jīng)典,是感覺既然當(dāng)了斑竹,就該留下點什么。lp這幾天也半開玩笑半生氣的說,一回來就上經(jīng)典,就發(fā)帖,你干脆娶經(jīng)典作lp得了。想想,這幾天是有點夸張,以后放慢速度了。保持1星期1帖吧,那樣也能多想寫,多總結(jié)些。 發(fā)帖的初衷就是有時候看到有的朋友問的問題,似乎還沒有走進java的門,希望這樣的帖子,能對新手一點幫助,也就滿足了。有時候隨意的一段話,其實也是自己的一點經(jīng)驗,而有時候之所以絮絮叨叨,是想把問題說的清楚明白,讓高手見笑了。因為在入門的時候,每一個小環(huán)節(jié)都可能郁悶半天,如果看到我的某段話,有所幫助的話,即使我說十句有一句有幫助,我也滿足了。因為我在不停的說話。
現(xiàn)在把總結(jié)的jsp頁面上傳類發(fā)布出來。代碼肯定還會存在問題,有bug的話,告訴我,我及時修正。
名稱:jsp頁面上傳類 作者:SinNeR Mail:vogoals[at]hotmail.com
特點:
- 可以多文件上傳;
- 返回上傳后的文件名;
- form表單中的其他參數(shù)也可以得到。
先貼上傳類,JspFileUpload
package com.vogoal.util; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Hashtable; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; /* * vogoalAPI 1.0 * Auther SinNeR@blueidea.com * by vogoal.com * mail: vogoals@hotmail.com */ /** * JSP上傳文件類 * * @author SinNeR * @version 1.0 */ public class JspFileUpload { /** request對象 */ private HttpServletRequest request = null; /** 上傳文件的路徑 */ private String uploadPath = null; /** 每次讀取得字節(jié)的大小 */ private static int BUFSIZE = 1024 * 8; /** 存儲參數(shù)的Hashtable */ private Hashtable paramHt = new Hasptable(); /** 存儲上傳的文件的文件名的ArrayList */ private ArrayList updFileArr = new ArrayList(); /** * 設(shè)定request對象。 * * @param request * HttpServletRequest request對象 */ public void setRequest(HttpServletRequest request) { this.request = request; } /** * 設(shè)定文件上傳路徑。 * * @param path * 用戶指定的文件的上傳路徑。 */ public void setUploadPath(String path) { this.uploadPath = path; } /** * 文件上傳處理主程序。�������B * * @return int 操作結(jié)果 0 文件操作成功;1 request對象不存在。 2 沒有設(shè)定文件保存路徑或者文件保存路徑不正確;3 * 沒有設(shè)定正確的enctype;4 文件操作異常。 */ public int process() { int status = 0; // 文件上傳前,對request對象,上傳路徑以及enctype進行check。 status = preCheck(); // 出錯的時候返回錯誤代碼。 if (status != 0) return status; try { // ��參數(shù)或者文件名�u�� String name = null; // 參數(shù)的value String value = null; // 讀取的流是否為文件的標(biāo)志位 boolean fileFlag = false; // 要存儲的文件。 File tmpFile = null; // 上傳的文件的名字 String fName = null; FileOutputStream baos = null; BufferedOutputStream bos = null; // ��存儲參數(shù)的Hashtable paramHt = new Hashtable(); updFileArr = new ArrayList(); int rtnPos = 0; byte[] buffs = new byte[BUFSIZE * 8]; // �取得ContentType String contentType = request.getContentType(); int index = contentType.indexOf("boundary="); String boundary = "--" + contentType.substring(index + 9); String endBoundary = boundary + "--"; // �從request對象中取得流。 ServletInputStream sis = request.getInputStream(); // 讀取1行 while ((rtnPos = sis.readLine(buffs, 0, buffs.length)) != -1) { String strBuff = new String(buffs, 0, rtnPos); // 讀取1行數(shù)據(jù)�n�� if (strBuff.startsWith(boundary)) { if (name != null && name.trim().length() > 0) { if (fileFlag) { bos.flush(); baos.close(); bos.close(); baos = null; bos = null; updFileArr.add(fName); } else { Object obj = paramHt.get(name); ArrayList al = new ArrayList(); if (obj != null) { al = (ArrayList) obj; } al.add(value); System.out.println(value); paramHt.put(name, al); } } name = new String(); value = new String(); fileFlag = false; fName = new String(); rtnPos = sis.readLine(buffs, 0, buffs.length); if (rtnPos != -1) { strBuff = new String(buffs, 0, rtnPos); if (strBuff.toLowerCase().startsWith( "content-disposition: form-data; ")) { int nIndex = strBuff.toLowerCase().indexOf( "name=\""); int nLastIndex = strBuff.toLowerCase().indexOf( "\"", nIndex + 6); name = strBuff.substring(nIndex + 6, nLastIndex); } int fIndex = strBuff.toLowerCase().indexOf( "filename=\""); if (fIndex != -1) { fileFlag = true; int fLastIndex = strBuff.toLowerCase().indexOf( "\"", fIndex + 10); fName = strBuff.substring(fIndex + 10, fLastIndex); fName = getFileName(fName); if (fName == null || fName.trim().length() == 0) { fileFlag = false; sis.readLine(buffs, 0, buffs.length); sis.readLine(buffs, 0, buffs.length); sis.readLine(buffs, 0, buffs.length); continue; }else{ fName = getFileNameByTime(fName); sis.readLine(buffs, 0, buffs.length); sis.readLine(buffs, 0, buffs.length); } } } } else if (strBuff.startsWith(endBoundary)) { if (name != null && name.trim().length() > 0) { if (fileFlag) { bos.flush(); baos.close(); bos.close(); baos = null; bos = null; updFileArr.add(fName); } else { Object obj = paramHt.get(name); ArrayList al = new ArrayList(); if (obj != null) { al = (ArrayList) obj; } al.add(value); paramHt.put(name, al); } } } else { if (fileFlag) { if (baos == null && bos == null) { tmpFile = new File(uploadPath + fName); baos = new FileOutputStream(tmpFile); bos = new BufferedOutputStream(baos); } bos.write(buffs, 0, rtnPos); baos.flush(); } else { System.out.println("test :" + value + "--" + strBuff); value = value + strBuff; } } } } catch (IOException e) { status = 4; } return status; } private int preCheck() { int errCode = 0; if ( request == null ) return 1; if ( uploadPath == null || uploadPath.trim().length() == 0 ) return 2; else{ File tmpF = new File(uploadPath); if (!tmpF.exists()) return 2; } String contentType = request.getContentType(); if ( contentType.indexOf("multipart/form-data") == -1 ) return 3; return errCode; } public String getParameter(String name){ String value = ""; if ( name == null || name.trim().length() == 0 ) return value; value = (paramHt.get(name) == null)?"":(String)((ArrayList)paramHt.get(name)).get(0); return value; } public String[] getParameters(String name){ if ( name == null || name.trim().length() == 0 ) return null; if ( paramHt.get(name) == null ) return null; ArrayList al = (ArrayList)paramHt.get(name); String[] strArr = new String[al.size()]; for ( int i=0;i<al.size();i++ ) strArr[i] = (String)al.get(i); return strArr; } public int getUpdFileSize(){ return updFileArr.size(); } public String[] getUpdFileNames(){ String[] strArr = new String[updFileArr.size()]; for ( int i=0;i<updFileArr.size();i++ ) strArr[i] = (String)updFileArr.get(i); return strArr; } private String getFileName(String input){ int fIndex = input.lastIndexOf("\\"); if (fIndex == -1) { fIndex = input.lastIndexOf("/"); if (fIndex == -1) { return input; } } input = input.substring(fIndex + 1); return input; } private String getFileNameByTime(String input){ int index = input.indexOf("."); Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); return input.substring(0,index) + sdf.format(dt) + input.substring(index); } }
說明:
這個類基本解決了上一貼的上一貼說的存在的bug和不足。主要做了如下修正。
- 用戶可以設(shè)定文件上傳的路徑,這里沒有用request對象的getRealPath方法來取得相對路徑,而是用了絕對路徑。是一個小敗筆。因為有時候用戶只是得到服務(wù)器的一個應(yīng)用,而不知道整個服務(wù)器的路徑。但是既然getRealPath自己可以得到,用戶自己取得也可以。
- 在文件上傳處理的時候,預(yù)先進行了check,把一些可能出現(xiàn)的造成上傳失敗的情況拍查掉。避免該類出現(xiàn)不該出現(xiàn)的異常。
- 捕獲了IO異常,避免文件上傳的時候出現(xiàn)異常時程序的不友好表現(xiàn)
- 提供了方法返回form表單中其他參數(shù)的取得,模擬了HttpServletRequest對象的getParameter和getParameters方法(后面這個方法是叫這個名字么-_-b),取得Parameter的名稱的方法沒有提供,是個小缺陷。
- 提供了方法返回上傳的文件的件數(shù)和上傳的文件名,方便用戶作其他操作。
現(xiàn)在介紹下JSP頁面中如何用這個類實現(xiàn)上傳。
首先,要把這個類編譯后的class文件拷貝到WEB-INF/classes/目錄下。注意保持package的結(jié)構(gòu)。
在jsp頁面中引用這個類
<%@page import="com.vogoal.util.JspFileUpload"%>
<% //初始化 JspFileUpload jfu = new JspFileUpload(); //設(shè)定request對象 jfu.setRequest(request); //設(shè)定上傳的文件路徑 jfu.setUploadPath("C:\\"); //上傳處理 int rtn = jfu.process(); //取得form中其他input控件參數(shù)的值 String username = jfu.getParameter("username"); //如果對應(yīng)同一個參數(shù)有多個input控件,返回數(shù)組 String[] usernameArr = jfu.getParameters("username"); //取得上傳的文件的名字 String[] fileArr = jfu.getUpdFileNames(); //取得上傳文件的個數(shù),這個方法有點雞肋 int fileNumber = jfu.getUpdFileSize(); //下面的是測試輸出的代碼。 // out.println("parameter:" + username); // out.println("parameter size:" + usernameArr.length); // out.println("fileArr size:" + fileArr.length); // if (fileArr.length > 0) // out.println("fileArr 0:" + fileArr[0]); %>
使用的時候的注意事項:
- 一定要設(shè)定request對象。
- 一定要設(shè)定正確的上傳路徑。
- 執(zhí)行完了之后才可以得到其他參數(shù),因為執(zhí)行了之后這些參數(shù)才被分析。
1,2兩點如果沒有做到的話,process方法執(zhí)行的時候匯報錯。
各個用戶可用的方法及說明:
設(shè)定requet對象。 public void setRequest(HttpServletRequest request)
設(shè)定文件上傳的路徑。 public void setUploadPath(String path)
文件上傳處理主程序。 @return int 操作結(jié)果 0 文件操作成功;1 request對象不存在。 2 沒有設(shè)定文件保存路徑或者文件保存路徑不正確;3 沒有設(shè)定正確的enctype;4 文件操作異常。 public int process()
根據(jù)name取得form表單中其他傳遞的參數(shù)的值(多個的話返回其中一個) public String getParameter(String name)
根據(jù)name取得form表單中其他傳遞的參數(shù)的值(返回數(shù)組,可有多個) public String[] getParameters(String name)
取得上傳成功文件的個數(shù) public int getUpdFileSize()
取得上傳的文件名對應(yīng)的數(shù)組。 public String[] getUpdFileNames()
注意process方法地返回值,在不是0的情況下操作失敗。
以下提供測試類以及測試頁面(見附件):
HelloPostFile.html HelloPostFile.jsp 寫在jsp中的代碼的測試文件。 HelloPostFileWithClass.html HelloPostFileWithClass.jsp 抽出class后的測試文件。 src在 WEB-INF/src/ class在 WEB-INF/classes/
另: 由于這個文件被我在中文日文系統(tǒng)下編輯過,注釋出現(xiàn)亂碼,所以大部分都刪掉了,見諒。
下載:WEB-INF.zip
出處:藍色理想
責(zé)任編輯:moby
上一頁 下一頁 jsp頁面實現(xiàn)文件下載
◎進入論壇網(wǎng)絡(luò)編程版塊參加討論
|