jsp文件上傳大多采用采用開源項(xiàng)目來簡化處理,這里是自己代碼實(shí)現(xiàn)jsp文件上傳、下載
一、文件上傳
上傳文件是Web開發(fā)中經(jīng)常要用到的功能:例如在基于B/S的人事信息管理系統(tǒng)中上傳照片,在新聞發(fā)布系統(tǒng)中上傳圖片等等。。。。。要實(shí)現(xiàn)文件上傳功能,就需要綜合利用java中的文件輸入和輸出相關(guān)的類。
在TCP/IP中,最早出現(xiàn)的文件上傳機(jī)制是FTP。它是將文件由客服端發(fā)送到服務(wù)器的標(biāo)準(zhǔn)機(jī)制,能夠考慮到跨平臺(tái)的文本和二進(jìn)制格式文件。但是在jsp編程中不能使用FTP方法來上傳文件,這是由jsp 運(yùn)行機(jī)制所決定的。
下面是上傳文件的jsp頁面:
1 <form action="file?file=upload" method="post" enctype="multipart/form-data"> 2 請(qǐng)選擇你要上傳的文件:<input type="file" name="upload" siez="16"><br> 3 <input type="submit" value="提交"> 4 </form>
對(duì)于文件上傳表單處理其中method必須為post,也要增加類型enctype="multipart/form-data"。這樣就可以把文件中的數(shù)據(jù)作為流式數(shù)據(jù)上傳。當(dāng)然無論是什么文件格式,均可以。。。
下面是servlet 處理程序:
1 //接收上傳文件內(nèi)容中臨時(shí)文件的文件名 2 String tempFileName = new String("tempFileName"); 3 //tempfile 對(duì)象指向臨時(shí)文件 4 File tempFile = new File("D:/"+tempFileName); 5 //outputfile 文件輸出流指向這個(gè)臨時(shí)文件 6 FileOutputStream outputStream = new FileOutputStream(tempFile); 7 //得到客服端提交的所有數(shù)據(jù) 8 InputStream fileSourcel = request.getInputStream(); 9 //將得到的客服端數(shù)據(jù)寫入臨時(shí)文件 10 byte b[] = new byte[1000]; 11 int n ; 12 while ((n=fileSourcel.read(b))!=-1){ 13 outputStream.write(b,0,n); 14 } 15 16 //關(guān)閉輸出流和輸入流 17 outputStream.close(); 18 fileSourcel.close(); 19 20 //randomFile對(duì)象指向臨時(shí)文件 21 RandomAccessFile randomFile = new RandomAccessFile(tempFile,"r"); 22 //讀取臨時(shí)文件的第一行數(shù)據(jù) 23 randomFile.readLine(); 24 //讀取臨時(shí)文件的第二行數(shù)據(jù),這行數(shù)據(jù)中包含了文件的路徑和文件名 25 String filePath = randomFile.readLine(); 26 //得到文件名 27 int position = filePath.lastIndexOf('\\'); 28 CodeToString codeToString = new CodeToString(); 29 String filename = codeToString.codeString(filePath.substring(position,filePath.length()-1)); 30 //重新定位讀取文件指針到文件頭 31 randomFile.seek(0); 32 //得到第四行回車符的位置,這是上傳文件數(shù)據(jù)的開始位置 33 long forthEnterPosition = 0; 34 int forth = 1; 35 while((n=randomFile.readByte())!=-1&&(forth<=4)){ 36 if(n=='\n'){ 37 forthEnterPosition = randomFile.getFilePointer(); 38 forth++; 39 } 40 } 41 42 //生成上傳文件的目錄 43 File fileupLoad = new File("D:/work space/JSP workspace/jsp_servlet_upAndLoad/file","upLoad"); 44 fileupLoad.mkdir(); 45 //saveFile 對(duì)象指向要保存的文件 46 File saveFile = new File("D:/work space/JSP workspace/jsp_servlet_upAndLoad/file/upLoad",filename); 47 RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,"rw"); 48 //找到上傳文件數(shù)據(jù)的結(jié)束位置,即倒數(shù)第四行 49 randomFile.seek(randomFile.length()); 50 long endPosition = randomFile.getFilePointer(); 51 int j = 1; 52 while((endPosition>=0)&&(j<=4)){ 53 endPosition--; 54 randomFile.seek(endPosition); 55 if(randomFile.readByte()=='\n'){ 56 j++; 57 } 58 } 59 60 //從上傳文件數(shù)據(jù)的開始位置到結(jié)束位置,把數(shù)據(jù)寫入到要保存的文件中 61 randomFile.seek(forthEnterPosition); 62 long startPoint = randomFile.getFilePointer(); 63 while(startPoint<endPosition){ 64 randomAccessFile.write(randomFile.readByte()); 65 startPoint = randomFile.getFilePointer(); 66 } 67 //關(guān)閉文件輸入、輸出 68 randomAccessFile.close(); 69 randomFile.close(); 70 tempFile.delete();
其中CodeToString()方法是一個(gè)中文字符處理的方法。如果文件不進(jìn)行編碼轉(zhuǎn)換,則上傳后的文件名將會(huì)是亂碼,接收的文件數(shù)據(jù)也會(huì)是亂碼:
下面是CodeToString()源代碼:
1 //處理中文字符串的函數(shù) 2 public String codeString(String str){ 3 String s = str; 4 try { 5 byte[] temp = s.getBytes("utf-8"); 6 s = new String(temp); 7 return s ; 8 } catch (UnsupportedEncodingException e) { 9 e.printStackTrace(); 10 return s; 11 } 12 }
二:文件下載
實(shí)現(xiàn)文件下載的最簡單的方法就是使用超鏈接。假設(shè)在服務(wù)器上web目錄下地upload子目錄存在user.doc這個(gè)文檔。如:
<a href="http://localhost:8080/upload/user.doc">下載user.doc</a>
當(dāng)單擊這個(gè)超級(jí)鏈接時(shí),將會(huì)在瀏覽器中直接打開這個(gè)文檔,就像是把word軟件嵌入在瀏覽器中一樣。
打開文檔后就可以實(shí)現(xiàn)另存為了。當(dāng)然在web上,最常見的方式是單擊鏈接后,出現(xiàn)“另存為”對(duì)話框:
1 //獲取要下載的文件名 2 String filename = request.getParameter("name"); 3 //得到想客服端輸出的輸出流 4 OutputStream outputStream = response.getOutputStream(); 5 //輸出文件用的字節(jié)數(shù)組,每次向輸出流發(fā)送600個(gè)字節(jié) 6 byte b[] = new byte[600]; 7 //要下載的文件 8 File fileload = new File("D:/work space/JSP workspace/jsp_servlet_upAndLoad/file/upLoad",filename); 9 //客服端使用保存文件的對(duì)話框 10 response.setHeader("Content-disposition", "attachment;filename="+filename); 11 //通知客服文件的MIME類型 12 response.setContentType("application/msword"); 13 //通知客服文件的長度 14 long fileLength = fileload.length(); 15 String length = String.valueOf(fileLength); 16 response.setHeader("Content_length", length); 17 //讀取文件,并發(fā)送給客服端下載 18 FileInputStream inputStream = new FileInputStream(fileload); 19 int n = 0; 20 while((n=inputStream.read(b))!=-1){ 21 outputStream.write(b,0,n); 22 }
在該程序中,response對(duì)象的setContentType()用來定義服務(wù)器發(fā)送給客服端內(nèi)容的MIME類型。這里對(duì)MIME就不特別介紹了。事實(shí)上,凡是瀏覽器能處理的所有資源都有對(duì)應(yīng)的MIME資源類型。在與服務(wù)器的交互中,瀏覽器就是對(duì)html、jsp等文件瀏覽器直接將其打開。對(duì)于word、excel等瀏覽器自身不能打開的文件則調(diào)用相應(yīng)的方法。對(duì)于沒有標(biāo)記MIME類型的文件。瀏覽器則根據(jù)其擴(kuò)展名和文件內(nèi)容猜測其類型。。。
每一個(gè)不曾起舞的日子,都是對(duì)未來的一種辜負(fù).