Java程式員從笨鳥到菜鳥之(七十一)細談struts2(十三)struts2實現檔案上傳和下載詳解

來源:互聯網
上載者:User

       

           檔案上傳和檔案下載是我們在web應用程式中常用的兩個功能,在java中,實現這兩種功能的方式也有很多種,其中struts2就給我們提供了一種算是比較簡單的方式吧,下面我們就一起來看一下,首先我們來看檔案上傳:


 檔案上傳

         檔案上傳我們首先應該注意的是在上傳頁面的表單,這個表單也是有講究的,由於我們提交表單的資料中有檔案上傳,所以這個表單的所使用的編碼類別型就不能是原來的了,在這裡我們應該使用的編碼方式是multipart/form-data,並且資料提交方式要用post方式,下面我們具體來看一下:

Form.jsp:

<form action="StudentAction!addStu" target="mainFrame" onsubmit="javascript:window.close()" method="post" enctype="multipart/form-data"><table class="ta" width="200px"><td>姓名</td><td><input type="text" name="stu.name" value="${request.stu_info.name }"/></td></tr><tr bgColor="#6fdd0"><td>上傳頭像</td><td><input type="file" name="file" />       </td></tr><tr bgColor="#6fdd0"><td colspan="2"><input type="submit"  value="提交" class="buStyle"/>     <input type="reset"  value="重設" class="buStyle"/></td></tr></table></form>

     OK,看完表單以後我們就要來看一下action裡面是怎麼來接收這些資料的,其實也很簡單,直接在action中定義三個變數,這三個變數分別是檔案、檔案名稱,還有檔案類型,如下:

private File file;private String fileFileName;private String fileContentType;

        這三個變數的名字是有講究的,不是隨便命名就OK了,其中file這個變數名要和表單中檔案的name要相同,fileFileName這個也是固定的,起名格式就是name+FileName,同樣fileContentType也是如此,命名規則是name+ContentType,只有你按照命名規則來定義變數,struts2才能把檔案上傳相關資訊收集起來。Ok,看完了變數設定,下面我們來看一下怎麼struts2是怎麼把檔案上傳到我們指定的位置的。那我們就先上代碼,讓代碼幫我們來理解:

String root = ServletActionContext.getRequest().getRealPath("/upload");try{InputStream is = new FileInputStream(file);// 建立一個檔案,路徑為root,檔案名稱叫fileFileName//自訂檔案名稱fileFileName="111"+fileFileName.substring(fileFileName.lastIndexOf("."));File destFile = new File(root, fileFileName);// 開始上傳OutputStream os = new FileOutputStream(destFile);byte[] buffer = new byte[50000];int length = 0;// enctype="multipart/form-data"while (-1 != (length = is.read(buffer))) {os.write(buffer, 0, length);}

      我們可以看到,就是簡單的幾行代碼,其實並不難,他主要就是利用了IO流來實現的檔案上傳。單檔案上傳實現以後,多檔案上傳實現起來就不難了。


多檔案上傳

與單檔案上傳相似,Struts 2實現多檔案上傳也很簡單。你可以使用多個<s:file />綁定Action的數組或列表。

< s:form action ="doMultipleUploadUsingList" method ="POST" enctype ="multipart/form-data" >     < s:file label ="File (1)" name ="upload" />     < s:file label ="File (2)" name ="upload" />     < s:file label ="FIle (3)" name ="upload" />     < s:submit /> </ s:form >


如果你希望綁定到數組,Action的代碼應類似:

   

  private File[] uploads;     private String[] uploadFileNames;     private String[] uploadContentTypes;     public File[] getUpload() { return this .uploads; }      public void setUpload(File[] upload) { this .uploads = upload; }       public String[] getUploadFileName() { return this .uploadFileNames; }      public void setUploadFileName(String[] uploadFileName) { this .uploadFileNames = uploadFileName; }       public String[] getUploadContentType() { return this .uploadContentTypes; }      public void setUploadContentType(String[] uploadContentType) { this .uploadContentTypes = uploadContentType; }

如果你想綁定到列表,則應類似:


     

private List < File > uploads = new ArrayList < File > ();     private List < String > uploadFileNames = new ArrayList < String > ();     private List < String > uploadContentTypes = new ArrayList < String > ();     public List < File > getUpload() {         return this .uploads;    }      public void setUpload(List < File > uploads) {         this .uploads = uploads;    }       public List < String > getUploadFileName() {         return this .uploadFileNames;    }      public void setUploadFileName(List < String > uploadFileNames) {         this .uploadFileNames = uploadFileNames;    }       public List < String > getUploadContentType() {         return this .uploadContentTypes;    }      public void setUploadContentType(List < String > contentTypes) {         this .uploadContentTypes = contentTypes;    }

    收集好資料之後,檔案上傳步驟就和上面單檔案的一樣了。在這就不重複了。好了,檔案上傳占時先說到這,下一步我們來看一下檔案下載。

檔案下載

          Struts 2中對檔案下載做了直接的支援,相比起自己辛辛苦苦的設定種種HTTP頭來說,現在實現檔案下載無疑要簡便的多。說起檔案下載,最直接的方式恐怕是直接寫一個超連結,讓地址等於被下載的檔案,例如:<a href=”file1.zip”> 下載file1.zip</a> ,之後使用者在瀏覽器裡面點擊這個連結,就可以進行下載了。但是它有一些缺陷,例如如果地址是一個圖片,那麼瀏覽器會直接開啟它,而不是顯示儲存檔案的對話方塊。再比如如果檔案名稱是中文的,它會顯示一堆URL編碼過的檔案名稱例如%3457...。而假設你企圖這樣下載檔案:http://localhost:8080/struts2/download/java程式員由笨鳥到菜鳥.doc ,Tomcat會告訴你一個檔案找不到的404錯誤:HTTP Status 404 - /struts2hello/download/ϵͳ˵Ã÷.doc 。 所以在此我們就要用到struts 給我們提供的檔案下載了。下面我們就一起來看一下struts2給我們提供的檔案下載:

其實struts2提供給我們的檔案下載已經非常簡單化了,編寫一個普通的Action就可以了,只需要提供一個返回InputStream流的方法,該輸入資料流代表了被下載檔案的入口,這個方法用來給被下載的資料提供輸入資料流,意思是從這個流讀出來,再寫到瀏覽器那邊供下載。這個方法需要由開發人員自己來編寫,只需要傳回值為InputStream即可 。首先我們來看一下jsp頁面:

 <body>      <h1>檔案下載</h1>      <!-- 下載連結 -->      <s:a action="down.action">download</s:a>    </body>  

頁面很簡單,就一下下載的連結,然後這個網站連結接到我們的action中,下一步我們來看一下我們的action的編寫:

public class DownAction extends ActionSupport {     private static final long serialVersionUID = 1L;    private String inputPath;    public String getInputPath() {        return inputPath;    }    public void setInputPath(String inputPath) {        this.inputPath = inputPath;    }    /*     * 下載用的Action應該返回一個InputStream執行個體,該方法對應在result裡的inputName屬性為     * getDownloadFile     */    public InputStream getDownloadFile()    {        return ServletActionContext.getServletContext().getResourceAsStream(        "/upload/Struts2.txt");    }    public String execute() throws Exception    {
return SUCCESS;
}
}

下面我們在來看一下struts.xml的配置:

       

 <action name="down" class="cn.csdn.hr.up.action.DownAction">            <!-- 配置結果類型為stream的結果 -->            <result name="success" type="stream">                <!-- 指定被下載檔案的檔案類型 -->                <param name="contentType">text/plain </param>                <!-- 指定下載檔案的檔案位置 -->                <param name="contentDisposition">attachment;filename="Struts2.txt"</param>                <param name="inputName">downloadFile</param>            </result>        </action>

這個action特殊的地方在於result的類型是一個流(stream ),配置stream類型的結果時,因為無需指定實際的顯示的實體資源,所以無需指定location 屬性,只需要指定inputName 屬性,該屬性指向被下載檔案的來源,對應著Action類中的某個屬性,類型為InputStream。下面則列出了和下載有關的一些參數列表:

參數說明

contentType

內容類型,和互連網MIME標準中的規定類型一致,例如text/plain代表純文字,text/xml表示XML,image/gif代表GIF圖片,image/jpeg代表JPG圖片

inputName

下載檔案的來源流,對應著action類中某個類型為Inputstream的屬性名稱,例如取值為inputStream 的屬性需要編寫getInputStream()方法

contentDisposition

檔案下載的處理方式,包括內聯(inline)和附件(attachment)兩種方式,而附件方式會彈出檔案儲存對話方塊,否則瀏覽器會嘗試直接顯示檔案。取值為:attachment;filename="struts2.txt" ,表示檔案下載的時候儲存的名字應為struts2.txt 。如果直接寫filename="struts2.txt" ,那麼預設情況是代表inline ,瀏覽器會嘗試自動開啟它,等價於這樣的寫法:inline; filename="struts2.txt"

bufferSize

下載緩衝區的大小

在這裡面,contentType 屬性和contentDisposition 分別對應著HTTP響應中的頭Content-Type 和Content-disposition 頭


當然,在很多的時候我們一般都不是把檔案名稱寫死在xml配置當中的,我們一般會在action中定義一個變數downfilename,儲存這個檔案名稱,然後再xml配置:

 <param name="contentDisposition">attachment;filename="${downloadFileName}"</param>

我們經常在中文下載中,出現檔案名稱亂碼的問題,這個問題是很多人都常見的,具體的很好的解決方案也沒有,但我以前用的時候嘗試著給他重新編碼,這樣可以解決大部分時候的中文下載亂碼問題,但有時候也不行的。具體重新編碼就是:

downFileName = new String(downFileName.getBytes(), "ISO8859-1");    

    好了,struts2檔案上傳和下載就簡單介紹到這,文章中有什麼不對或者錯誤的地方,歡迎大家指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.