下載文件的兩種方式:
1.超鏈接的方式;
2.編程實現下載;
但是通過超鏈接下載文件,暴露了下載文件的真實地址,不利於對資源進行安全保護;而且利用超鏈接下載文件,服務器端的文件只能存放在Web應用程序所在的目錄下。
利用程序編碼實現下載,可以增加安全訪問控制,對經過授權認證的用戶提供下載,還可以任意提供下載的數據,我們可以將文件放到Web應用程序以外的目錄中,也可以將文件保存到數據庫中。此處實現的方式是利用編程的方式:需要按照如下的方式設置三個報頭域就可以了:
Content-Type:application/x-msdownload
Content-Disposition:attachment;filename=downloadfile
Content-Length:filesize
使用Struts2具體實現:
瀏覽器在接收到上述的報頭信息後, 就會彈出文件下載對話框,讓你將文件保存到本地硬盤。
Struts2通過org.apache.struts2.dispatcher.StreamResult結果類型來支持文件下載,使得原本編寫就簡單的下載程序變得更加簡單了。
StreamResult結果類型利用HttpServletResponse對象返回的ServletOutputStream對象向客戶端輸出下載文件的二進制數據,它有下列參數:
contentType:發送給Web瀏覽器的數據流的MIME類型(默認是text/plain),即下載文件內容類型
contentLength:數據流的長度,以字節爲單位(瀏覽器顯示一個進度欄),即下載文件的長度。
contentDisposition:用於控制文件下載的一些信息,可選擇的設置包括:inline;filename=“下載文件名”和attachment;filename=“下載文件名”,filename指定下載的文件名。Inline表示下載文件在本頁面內部打開,attachement表示彈出”文件下載”對話框。不過,這也不是絕對的,對於瀏覽器能夠顯示的下載文件是這樣的,對於瀏覽器不支持的下載類型,即使使用inline選項,仍然會彈出”文件下載”對話框。 contentDisposition的默認值是inline.
inputName:Action中用來下載文件的屬性的名字,該屬性的類型是InputStream.默認值是inputStream.
bufferSize:文件數據從輸入複製到輸出的緩衝區的大小,默認爲1024字節。
具體實現的實例:
struts.xml配置
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="fileDownAction" class="com.handler.FileDownAction" method="down">
<result type="stream">
<param name="contentType">application/x-msdownload</param>//設置抱頭信息
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${filename}"</param>//attachement表示彈出”文件下載”對話框
<param name="bufferSize">1024000</param>
</result>
</action>
</package>
</struts>
Action域:
package com.handler;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class FileDownAction extends ActionSupport{
private String filename;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
private InputStream inputStream;
public InputStream getInputStream() throws FileNotFoundException {
String path=ServletActionContext.getServletContext().getRealPath("/files/"+filename);
File file=new File(path);
inputStream =new FileInputStream(file);
return inputStream;
}
public String down(){
return SUCCESS;
}
}
運行結果: