技術要點
本節代碼詳細說明文件下載功能的開發流程,介紹知識點如下:
DownloadAction文件下載功能開發。
struts.xml中DownloadAction配置,以及支持文件名爲中文字符的文件下載。
下載文件流程展示。
演示代碼
上傳成功頁面,這裏筆者讓其在每個上傳文件後提供“下載”鏈接。
<!------------------------文件名:result.jsp------------------->
<%@taglib prefix="s" uri="/struts-tags"%>
<body>
上傳文件:
<table>
<!-- 循環顯示上傳成功文件名 -->
<s:iterator value="fileFileName" status="fn">
<tr>
<td>
<!-- 上傳成功文件名 -->
<s:property />
</td>
<td>
<!-- 下載文件鏈接內容爲定義的下載Action -->
<!-- 下載文件名作爲鏈接參數fileName值,用OGNL表達式表達 -->
<a href="<s:url value='download.action'>
<s:param name='fileName'
value='fileFileName[#fn.getIndex()]'/>
</s:url>">下載</a>
</td>
</tr>
</s:iterator>
</table>
</body>
DownLoadAction類代碼
<!------------文件名:DownLoadAction.java ------------------>
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownLoadAction extends ActionSupport {
//下載文件原始存放路徑
private final static String DOWNLOADFILEPATH="/upload/";
//文件名參數變量
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
//從下載文件原始存放路徑讀取得到文件輸出流
public InputStream getDownloadFile() {
return
ServletActionContext.getServletContext().getResourceAsStream(DOWNLOADFILEPATH+fileName);
}
//如果下載文件名爲中文,進行字符編碼轉換
public String getDownloadChineseFileName() {
String downloadChineseFileName = fileName;
try {
downloadChineseFileName = new String(downloadChineseFileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downloadChineseFileName;
}
public String execute() {
return SUCCESS;
}
}
struts.xml配置文件中有關文件下載的配置:
<!------------------文件名:struts.xml----------------->
<struts>
<!-- 下載文件的Action定義 -->
<action name="download" class="action.DownLoadAction">
<!-- 設置文件名參數,由頁面上傳入 -->
<param name="fileName"></param>
<result name="success" type="stream">
<!-- 下載文件類型定義 -->
<param name="contentType">text/plain</param>
<!-- 下載文件處理方法 -->
<param name="contentDisposition">
attachment;filename="${downloadChineseFileName}"
</param>
<!-- 下載文件輸出流定義 -->
<param name="inputName">downloadFile</param>
</result>
</action>
</struts>
代碼解釋
(1)在result.jsp中通過iterator標籤和url標籤定義了“fileFileName”的循環顯示以及鏈接。其中有關“status”和OGNL表達式筆者會在之後章節裏具體介紹,這裏只是讓讀者知道是如何使用標籤顯示圖4.12顯示的內容。特別指出<param>標籤爲downloadAction定義了一個參數,該參數名爲“fileName”,因爲在4.4.1小節中筆者定義的“fileFileName”是個List類型的數據集合,因此利用OGNL表達式將文件名作爲“fileName”參數值傳入downloadAction中。
(2)DownLoadAction文件中先定義了常量DOWNLOADFILEPATH,它是下載文件在服務器存放的路徑名,也就是4.4.1小節中上傳文件在服務器存放的路徑名。
定義好DOWNLOADFILEPATH後,在定義DownLoadAction的屬性變量。因爲在result.jsp中定義了參數“fileName”,則它作爲DownLoadAction的屬性變量,需要定義相應的getter、setter方法。
然後定義了getDownloadFile方法,它返回的是一個文件流,表明將被下載文件轉換爲輸出流,方便下載。利用Struts2自帶的“ServletActionContext”類的API把下載文件存放路徑作爲方法參數,讀取下載文件,將其轉換爲文件流。
還有一個getDownloadChineseFileName方法,該方法主要作用是將文件名爲中文字符的文件進行文件名的字符編碼集合轉換。因爲在Web系統中由JSP等視圖頁面傳入的變量值,特別是中文字符的變量。缺省的字符編碼集合都是“ISO8859-1”,因此利用Java的字符串類的API,將字符編碼轉成開發需要的字符編碼集。防止中文字符亂碼問題發生。
(3)struts.xml中定義了名爲“download”的Action。其中它自己的參數“fileName”因爲在這裏它的值會從JSP頁面上傳入,所以這裏只是定義,沒有具體給它賦任何值
在<result>標籤中定義了type屬性,值爲“stream”。如果是下載文件功能開發,DownLoadAction一定要設置type屬性,而且值爲“stream”。這是因爲在Struts2自帶的xml配置文件爲struts-default.xml中有關於“stream”的result返回類型的定義,代碼如下:
<!-------------------文件名:struts-default.xml-------------->
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
這裏Struts2定義了result返回類型爲“stream”,這個result類型主要是處理文件的輸入和輸出流時候需要使用的。因爲下載文件就是把文件轉換成輸入輸出流,將其從一個文件路徑放到另外一個文件路徑中去。所以肯定要設置這個result類型的。
“contentType”、“contentDisposition”、“inputName”都是這個result的屬性。“contentType”就是文件類型。這裏因爲下載的文件是文本文件,因此設定的值爲文本文件類型,具體各個文件類型如何定義,4.4.1小節已經介紹過,這裏不再做說明。“contentDisposition”是指定下載文件處理方式,如圖4.13就是處理方式的效果。特別指出如果“contentDisposition”定義的值把前面的“attachment”去掉,則下載方式不是以附件方式下載,如果單擊“下載”鏈接,則會把下載文件的內容顯示在瀏覽器中。讀者可以去試驗一下。這裏有個“${downloadChineseFileName}”,這就是在DownLoadAction中定義getDownloadChineseFileName方法的目的,${downloadChineseFileName}是OGNL的表達式,它顯示了“downloadChineseFileName”變量的具體值,因爲在DownLoadAction中定義getDownloadChineseFileName方法,則把已經轉換成符合需要字符編碼集的下載文件名作爲下載文件方式對話框中顯示的名稱,不會造成任何亂碼問題。“inputName”是最關鍵的一個屬性,也是一定要定義的屬性,“inputName”參數中定義的值“downloadFile”就是DownLoadAction中getDownloadFile方法返回的文件流名字。在Struts2中Acion用前綴名爲get的方法得到各種屬性的值,這些屬性有些是在Action中定義,有些就像本示例在配置文件中利用OGNL表達式或直接定義。
(4)開始進行文件下載功能展示,按照如上記述的步驟執行即可。筆者將兩個文本文件上傳上去,然後在上傳成功頁面對具體的文件進行下載。在圖4.13中單擊“保存”按鈕就顯示圖4.14,選擇在本機上存放下載文件的路徑即可完成下載文件功能。