StrutsFileUpload
文件上傳的簡單范例
HTML
HTML頁面需要做兩件事情,首先,表單需要指定enctype="multipart/form-dataand",其次需要一個類型為file的<input>表單控件。
?? <form name="myForm" method="post"
???????? action="/mywebapp/uploadMyFile.do"
???????? enctype="multipart/form-data">
???????? Select File: <input type="file" name="myFile">????????? </br>
???????? <input type="submit" value="Upload File">
?? </form>
JSP
上面的HTML標簽用Struts標簽代替就是以下代碼:
?? <html:form action="/uploadMyFile.do"?????????????? enctype="multipart/form-data">
???????? Select File: <html:file property="myFile"> </br>
???????? <html:submit value="Upload File"/>
?? </html:form>
ActionForm
這個ActionForm需要一個FormFile類型的字段。
一般的ActionForm
??? import org.apache.struts.upload.FormFile;
??? public class MyActionForm extends ActionForm {
?????? private FormFile myFile;
?????? public void setMyFile(FormFile myFile) {
?????????? this.myFile = myfile;
?????? }
?????? public FormFile getMyFile() {
?????????? return myFile;
?????? }
??? }
動態ActionForms
在struts-config.xml文件中寫上:
?? <form-bean name="myForm"???? type="org.apache.struts.action.DynaActionForm">
?????? <form-property name="myFile"???????? type="org.apache.struts.upload.FormFile"/>
?? </form-bean>
在Action中需要怎么寫呢?
其實沒什么特殊的,就象和得到其他屬性一樣,從ActionForm中得到FormFile屬性,得到后可以隨意進行處理。比如我們可以從FileForm中得到文件名,文件大小,文件內容
??? public ActionForward execute(ActionMapping mapping,
???????????????????????????????? ActionForm form,
???????????????????????????????? HttpServletRequest request,
???????????????????????????????? HttpServletResponse response)
???????????????????????????????? throws Exception {
??????? MyActionForm myForm = (MyActionForm)form;
??????? // Process the FormFile
??????? FormFile myFile = myForm.getMyFile();
??????? String contentType = myFile.getContentType();
??????? String fileName??? = myFile.getFileName();
??????? int fileSize?????? = myFile.getFileSize();
??????? byte[] fileData??? = myFile.getFileData();
??????? ...
??? }
文件上傳的配置
在struts-config.xml的<controller>element中可以設置如下參數來配置文件上傳:
bufferSize - 處理文件上傳的緩沖區大小,單位是字節。
默認是4096byte。
maxFileSize - 允許上傳文件的大小。可以使用K,M,G為單位。
默認是250M。
multipartClass - muiltpart請求處理器類的全局標識名。默認是org.apache.struts.upload.CommonsMultipartRequestHandler
tempDir - 處理文件上傳的臨時目錄。
還有一種可選的文件上傳插件的方式可提供使用,那就是實現
org.apache.struts.upload.MultipartRequestHandler接口。
可以在struts-config.xml的<controller>的multipartClass
來指定這個實現給接口的類。
====================================
StrutsFileDownload
Struts 1.2.6中推出了新的DownloadAction,用來簡化下載操作。
實現DownloadAction
我們需要擴展org.apache.struts.actions.DownloadAction并實現
getStreamInfo()方法。如果我們要更改默認的緩沖大小,我們也可以覆蓋
getBufferSize()方法。?
實現getStreamInfo() 方法
getStreamInfo() 方法返回一個StreamInfo對象- 它是DownloadAction類的內
部類,其實是個內部接口。DownloadAction為這個接口提供了兩個具體的靜態內
部實現類:
FileStreamInfo - 簡化從磁盤系統下載文件。需要連同content type傳入一個java.io.File對象到構造方法中。
ResourceStreamInfo - 簡化從web應用資源下載文件。需要傳入ServletContext,路徑以及content type 到它的構造方法中。
在下面的例子中,我們還提供了一個以Byte array方法實現StreamInfo接口的代
碼。
實現getBufferSize() 方法
DownloadAction默認返回4096byte的緩沖區我們可以覆蓋這個方法來自定義用
來傳輸文件的緩沖區大小
范例
下面有三個例子:
使用文件
使用web應用資源
使用byte array
FileStreamInfo范例
DownloadAction使用文件的例子。這個范例從struts-config.xml的action
mapping的parameter屬性來得到文件名。
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;
public class ExampleFileDownload extends DownloadAction{
??? protected StreamInfo getStreamInfo(ActionMapping mapping,
?????????????????????????????????????? ActionForm form,
?????????????????????????????????????? HttpServletRequest request,
?????????????????????????????????????? HttpServletResponse response)
??????????? throws Exception {
??????? // Download a "pdf" file - gets the file name from the
??????? // Action Mapping's parameter
??????? String contentType = "application/pdf";
??????? File file????????? = new File(mapping.getParameter());
??????? return new FileStreamInfo(contentType, file);
??? }
}
ResourceStreamInfo范例
DownloadAction使用web應用資源的范例。這個范例從struts-config.xml的
action mapping的parameter屬性來得到web應用資源的路徑。
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;
public class ExampleResourceDownload extends DownloadAction {
??? protected StreamInfo getStreamInfo(ActionMapping mapping,
?????????????????????????????????????? ActionForm form,
?????????????????????????????????????? HttpServletRequest request,
?????????????????????????????????????? HttpServletResponse response)
??????????? throws Exception {
??????? // Download a "jpeg" file - gets the file name from the
??????? // Action Mapping's parameter
??????? String contentType???????? = "image/jpeg";
??????? String path??????????????? = mapping.getParameter();
??????? ServletContext application = servlet.getServletContext();
??????? return new ResourceStreamInfo(contentType, application, path);
??? }
}
Byte Array 范例
DownloadAction使用字節數組(byte array)的范例。
這個例子創建了一個實現了StreamInfo接口的ByteArrayStreamInfo內部類。
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;
public class ExampleByteArrayDownload extends DownloadAction {
??? protected StreamInfo getStreamInfo(ActionMapping mapping,
?????????????????????????????????????? ActionForm form,
?????????????????????????????????????? HttpServletRequest request,
?????????????????????????????????????? HttpServletResponse response)
??????????? throws Exception {
??????? // Download a "pdf" file
??????? String contentType = "application/pdf";
??????? byte[] myPdfBytes? = null;// Get the bytes from somewhere
??????? return new ByteArrayStreamInfo(contentType, myPdfBytes);
??? }
??? protected class ByteArrayStreamInfo implements StreamInfo {
??????? protected String contentType;
??????? protected byte[] bytes;
??????? public ByteArrayStreamInfo(String contentType, byte[] bytes) {
??????????? this.contentType = contentType;
??????????? this.bytes = bytes;
??????? }
??????? public String getContentType() {
??????????? return contentType;
??????? }
??????? public InputStream getInputStream() throws IOException {
??????????? return new ByteArrayInputStream(bytes);
??????? }
??? }
}
在WEB頁面上使用DownloadAction
最大的疑惑是我么如何使用這個Action?
需要做兩件事情:
和任何Struts的action一樣,需要在struts-config.xml中進行配置。
在WEB頁面中使用它對文件進行連接
下面是struts-config.xml配置的一個例子:
??? <action path="/downloadMyPdfFile" type="myPackage.ExampleFileDownload"
????? parameter="/foo/bar.pdf">
??? <action path="/downloadMyImage"?? type="myPackage.ExampleResourceDownload"
????? parameter="/images/myImage.jpeg">
那么在我們的JSP頁面,可以使用類似下面的例子:
??? <html:img action="downloadMyImage" alt="My Image" height="400" width="400"/>
??? <html:link action="downloadMyPdfFile">Click Here to See the PDF</html:link>
注意:我們可能要將struts配置文件中<controller>屬性的nocache值設置為false。如果設置為true,可能在IE上不能成功下載文件,但是在Firefox和Safari上工作正常。
??? <controller contentType="text/html;charset=UTF-8" locale="true" nocache="false" />
內容部署(Content Disposition)
設置Content Disposition
DownloadAction不能處理content dispositon頭部。最簡單的方法是在getStreamInfo()方法中設置,比如:
public class ExampleFileDownload extends DownloadAction{
??? protected StreamInfo getStreamInfo(ActionMapping mapping,
?????????????????????????????????????? ActionForm form,
?????????????????????????????????????? HttpServletRequest request,
?????????????????????????????????????? HttpServletResponse response)
??????????? throws Exception {
??????? // File Name
??????? String fileName = mapping.getParameter();
??????? // Set the content disposition
??????? response.setHeader("Content-disposition",
?????????????????????????? "attachment; filename=" + new String(fileName.getBytes("gbk"), "iso8859_1"));// 設置文件名
??????? // Download a "pdf" file - gets the file name from the
??????? // Action Mapping's parameter
??????? String contentType = "application/pdf";
??????? File file????????? = new File(fileName);
??????? return new FileStreamInfo(contentType, file);
??? }
}
如果需要文件名做為參數,可能需要首先把文件前面的任何路徑信息先清除。
@@ Content Disposition的值
我們可以設置content disposition來下載一個文件或者在瀏覽器中打開一個文件。
在瀏覽器中打開文件的例子寫法: "inline; filename=myFile.pdf"
下載的例子寫法: "attachment; filename=myFile.pdf"
顯示圖片的話,可以使用content disposition的"inline"選項。
文章來源:http://x-spirit.spaces.live.com/Blog/cns!CC0B04AE126337C0!784.entry