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=" + fileName);
// 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"選項。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=644250