由response.setContentType()方法開始談JSP/Servelt上傳下載文件

[html] view plain copy html

  1.  文章非原創,參考連接見文末!  java

[html] view plain copy web

  1. 常見的MIME類型以下表:  json

序號瀏覽器

內容類型服務器

文件擴展名app

描述jsp

1post

application/msword測試

doc

Microsoft Word

2

application/octet-stream bin

dms lha lzh exe class

可執行程序

3

application/pdf

pdf

Adobe Acrobat

4

application/postscript

ai eps ps

PostScript

5

appication/powerpoint

ppt

Microsoft Powerpoint

6

appication/rtf

rtf

rtf 格式

7

appication/x-compress

z

unix 壓縮文件

8

application/x-gzip

gz

gzip

9

application/x-gtar

gtar

tar 文檔 (gnu 格式 )

10

application/x-shockwave-flash

swf

MacroMedia Flash

11

application/x-tar

tar

tar(4.3BSD)

12

application/zip

zip

winzip

13

audio/basic

au snd

sun/next 聲音文件

14

audio/mpeg

mpeg mp2

Mpeg 聲音文件

15

audio/x-aiff

mid midi rmf

Midi 格式

16

audio/x-pn-realaudio

ram ra

Real Audio 聲音

17

audio/x-pn-realaudio-plugin

rpm

Real Audio 插件

18

audio/x-wav

wav

Microsoft Windows 聲音

19

image/cgm

cgm

計算機圖形元文件

20

image/gif

gif

COMPUSERVE GIF 圖像

21

image/jpeg

jpeg jpg jpe

JPEG 圖像

22

image/png

png

PNG 圖像

text/html HTML 

text/plain          TXT 

text/xml             XML

text/json           json字符串

   此外不一樣瀏覽器下對同一個文件上傳後獲取到的類型可能不一樣。


一、文件下載:

   文件下載的關鍵代碼在於:

  response.setHeader("Content-disposition", "attachment;filename="

              + "test.rar");

  // set the MIME type.

  response.setContentType("application/x-tar");

  response.setHeader("Content_Length", length);

  即經過設置HttpServletResponse的各個屬性來實現。

  

   文件下載有一個最容易犯錯的地方是直接經過:<a href="test.txt">Download</a> 來實現,沒有這麼簡單的。若是你是經過相似這樣的路徑:file:///C:/test/down.html 假設前面這行代碼包含在 download.html中,那麼你或許能夠很順利地獲得,而若是這個html文件(或JSP文件)在Web服務器中好比Tomcat,那麼你點擊這個將沒有反應的。這時查看源代碼會發現連接內容變爲: http://localhost:8080/file:///c:/test/down.html ,我猜想多是這樣:當<a>標籤中指定的href值爲相對路徑時,Web服務器會默認在這個相對路徑前加上服務器根路徑。


   是否是有點暈?沒關係。其實搞懂這麼一個問題就好了。文件下載時,文件是存在Web服務器的某個目錄下的,或者說存在服務器的磁盤上的,那麼咱們能夠在Servlet中經過Java的File及相關API訪問文件,由於Servlet是在服務器端執行的而若是呈現給客戶端的頁面中有這麼一個連接:

   <a href="c:/test.txt">download it!</a>

   你說能正常獲取到服務器C盤的test.txt文件嘛?顯然獲取不到的。由於如今是在客戶端,因此href被Web服務器解析成 http://localhost:8080/file:///c:/test.txt 返回給客戶端。


   那麼該如何實現文件下載?不能直接使用包含盤符的文件路徑表示href,可是盤符路徑能夠用在Servelt中構造File對象,即將文件加載到Web服務器內存中,而後寫到響應流中返回給客戶端,即實現了。

  

   下面是代碼演示:

   主要包含 index.jsp、訪問路徑爲/loadFile的Servelt(名稱爲LoadFile),至於web.xml配置Servelt省略。

[html] view plain copy

  1. <html>  

  2. <head>  

  3.     <meta http-equiv="Content-Type" content="text/html; charset=GB18030">  

  4.     <title>download page</title>  

  5. </head>  

  6. <body>  

  7.     <a href="loadFile?filename=test.txt&path="+escape("C:/test.txt")>Download It!</a>  

  8. </body>  

  9. </html>  


  LoadFile類以下:

[java] view plain copy

  1. import java.io.File;  

  2. import java.io.FileInputStream;  

  3. import java.io.IOException;  

  4. import java.io.OutputStream;  

  5. import javax.servlet.ServletException;  

  6. import javax.servlet.http.HttpServlet;  

  7. import javax.servlet.http.HttpServletRequest;  

  8. import javax.servlet.http.HttpServletResponse;  

  9.    

  10. public class LoadFile extends HttpServlet {  

  11.     public void doGet(HttpServletRequest request, HttpServletResponse response)  

  12.            throws IOException, ServletException {  

[java] view plain copy

  1. String filename = request.getParameter("filename");  

[java] view plain copy

  1.        String path = request.getParameter("path");  

  2.        OutputStream o = response.getOutputStream();  

  3.        byte b[] = new byte[1024];  

  4.        // the file to download.  

  5.        File fileLoad = new File(path);  

  6.        // the dialogbox of download file.  

  7.        response.setHeader("Content-disposition""attachment;filename="  

  8.               + "test.txt");  

  9.        // set the MIME type.  

  10.        response.setContentType("text/html");  

  11.        // get the file length.  

  12.        long fileLength = fileLoad.length();  

  13.        String length = String.valueOf(fileLength);  

  14.        response.setHeader("Content_Length", length);  

  15.        // download the file.  

  16.        FileInputStream in = new FileInputStream(fileLoad);  

  17.        int n = 0;  

  18.        while ((n = in.read(b)) != -1) {  

  19.            o.write(b, 0, n);  

  20.        }  

  21.     }  

  22.    

  23.     public void doPost(HttpServletRequest request, HttpServletResponse response)  throws IOException, ServletException {  

  24.        doGet(request, response);  

  25.     }  

  26. }  

   即OK了。



2. 文件上傳

   雖然文件上傳和下載都能經過開源組件來實現,但若是要本身實現的話仍是費一番功夫的。文件上傳通常是經過<form>表單結 合<input type="file">來實現的。最後在服務端的Servlet中經過requst獲取輸入流,而後寫到服務器磁盤文件中去。雖然原理清楚了,但 是是否就能夠直接像下面這樣寫呢?

[java] view plain copy

  1. test.jsp  

  2. <%@page  contentType="text/html;charset=GB2312"%>  

  3. <html>  

  4. <body>  

  5.     選擇要上傳的文件:<br />  

  6.     <form action="accept.jsp" method="post" enctype="multipart/form-data">  

  7.    <input type="file" name="boy" size="38">  

  8.    <br />  

  9.    <input type="hidden" id="tt" name="t" value="1" />  

  10.    <input type="submit" id="gg" name="g" value="提交" />  

  11. </form>  

  12. </body>  

  13. </html>  

[java] view plain copy

  1.   

[java] view plain copy

  1. accept.jsp  

  2. <%@page  contentType="text/html;charset=GB2312"%>  

  3. <%@ page import="java.io.*"%>  

  4. <HTML>  

  5. <BODY>  

  6. <%  

  7. //經測試,說明:ServletInputStream類中的readLine(byte[] b, int off, int len)  

  8. //其中參數 byte[] b 起緩衝做用,此方法一次讀取一行,但若是 byte[] b 定義的大小,比要讀取的一行需佔用的空間要小,則  

  9. //該方法只讀取 byte[] b 指定的大小;再次讀取時會繼續接着上次未讀完的讀取;返回值 :返回實際讀取的字節數,當讀到文檔流的  

  10. //最後時返回-1。  

  11. try{  

  12.    ServletInputStream in=request.getInputStream();  

  13.    File f=new File("c:\\test","a.txt");  

  14.    FileOutputStream o=new FileOutputStream(f);  

  15.   

  16. //若是byte b[]=設置的值過短的話(假如設置爲2),那麼在 應用的 上傳操做時會有影響,具體表現爲沒法解析文檔路徑等相關信息  

  17. byte b[]=new byte[2046];  

  18.    int n;  

  19.    int i = 0;  

  20.    while((n=in.readLine(b,0,b.length))!=-1)//ServletInputStream.readLine方法是逐行讀取的。當它讀完整個文件,返回-1,通常狀況下返回讀取的字節數  

  21.    {  

  22.       i++;  

  23.       System.out.println("------"+i);  

  24.       o.write(b,0,n);  

  25.    }  

  26.    o.close();  

  27.    in.close();  

  28. }catch(IOException e){  

  29.    e.printStackTrace();  

  30. }  

  31. out.print("文件已經上傳");  

  32. %>  

  33. <a href="c:\\test\\a.txt">查看結果</a>  

  34. </body>  

  35. </HTML>  

   我上傳一個test.txt文件,其內容爲3行 Hello World!。以後打開C:\\test\a.txt,內容以下:

[html] view plain copy

  1. -----------------------------7db2611a404a4  

  2. Content-Disposition: form-data; name="boy"filename="C:\Users\xijiang\Desktop\test.txt"  

  3. Content-Type: text/plain  

  4.   

  5. Hello World!  

  6. Hello World!  

  7. Hello World!  

  8. -----------------------------7db2611a404a4  

  9. Content-Disposition: form-data; name="t"  

  10.   

  11. 1  

  12. -----------------------------7db2611a404a4  

  13. Content-Disposition: form-data; name="g"  

  14.   

  15. 提交  

  16. -----------------------------7db2611a404a4--  

    能夠很明顯看到內容不是咱們預期的只有三行Hello World!,還多了其餘的表單屬性值。觀察這個文件的內容格式,能夠大概看出,

[html] view plain copy

  1. -----------------------------7db2611a404a4  

[html] view plain copy

  1. 是字段間隔符。  

[html] view plain copy

  1. <pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">-----------------------------7db2611a404a4--</pre>  

  2. <pre></pre>  

  3. <pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">  是結束符。</pre><pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">  <input type="file">對應的值表示爲:</pre><pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; "><pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">-----------------------------7db2611a404a4  

  4. Content-Disposition: form-data; name="boy"filename="C:\Users\jxq\Desktop\test.txt"  

  5. Content-Type: text/plain  

  6.   

  7. Hello World!  

  8. Hello World!  

  9. Hello World!</pre><pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">   即第一行是 Content-Disposition、name和客戶端上傳的文件的目錄,第二行是上傳的文件類型,第三行是空行,接下來是文件內容。</pre><pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">   而表單提交的其餘屬性值則是經過 Content-Disposition: from-dat; name=xx 來表示。</pre><pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; ">   因此爲了獲取上傳的文件的真正內容,咱們不能簡單地讀取從request得到的輸入流,必須進一步解析。</pre>  

  10. <pre></pre>  

  11. <pre name="code" class="html" style="background-color: rgb(255, 255, 255); text-align: -webkit-left; "></pre></pre>  

  12. <pre></pre>  

  13. <pre></pre>  

  14. <pre></pre>

相關文章
相關標籤/搜索