Struts2教程:上傳任意多個文件
一、上傳單個文件
上傳文件是很多Web程序都具有的功能。在Struts1.x中已經(jīng)提供了用于上傳文件的組件。而在Struts2中提供了一個更為容易操作的上傳文件組件。所不同的是,Struts1.x的上傳組件需要一個ActionForm來傳遞文件,而Struts2的上傳組件是一個攔截器(這個攔截器不用配置,是自動裝載的)。在本文中先介紹一下如何用struts2上傳單個文件,***介紹一下用struts2上傳任意多個文件。
要用Struts2實現(xiàn)上傳單個文件的功能非常容易實現(xiàn),只要使用普通的Action即可。但為了獲得一些上傳文件的信息,如上傳文件名、上傳文件類型以及上傳文件的Stream對象,就需要按著一定規(guī)則來為Action類增加一些getter和setter方法。
在Struts2中,用于獲得和設(shè)置java.io.File對象(Struts2將文件上傳到臨時路徑,并使用java.io.File打開這個臨時文件)的方法是getUpload和setUpload。獲得和設(shè)置文件名的方法是getUploadFileName和setUploadFileName,獲得和設(shè)置上傳文件內(nèi)容類型的方法是getUploadContentType和setUploadContentType。下面是用于上傳的動作類的完整代碼:
- package action;
- import java.io.*;
- import com.opensymphony.xwork2.ActionSupport;
- public class UploadAction extends ActionSupport
- {
- private File upload;
- private String fileName;
- private String uploadContentType;
- public String getUploadFileName()
- {
- return fileName;
- }
- public void setUploadFileName(String fileName)
- {
- this.fileName = fileName;
- }
- public File getUpload()
- {
- return upload;
- }
- public void setUpload(File upload)
- {
- this.upload = upload;
- }
- public void setUploadContentType(String contentType)
- {
- this.uploadContentType=contentType;
- }
- public String getUploadContentType()
- {
- return this.uploadContentType;
- }
- public String execute() throws Exception
- {
- java.io.InputStream is = new java.io.FileInputStream(upload);
- java.io.OutputStream os = new java.io.FileOutputStream("d:\\upload\\" + fileName);
- byte buffer[] = new byte[8192];
- int count = 0;
- while((count = is.read(buffer)) > 0)
- {
- os.write(buffer, 0, count);
- }
- os.close();
- is.close();
- return SUCCESS;
- }
- }
在execute方法中的實現(xiàn)代碼就很簡單了,只是從臨時文件復(fù)制到指定的路徑(在這里是d:\upload)中。上傳文件的臨時目錄的默認(rèn)值是javax.servlet.context.tempdir的值,但可以通過struts.properties(和struts.xml在同一個目錄下)的struts.multipart.saveDir屬性設(shè)置。Struts2上傳文件的默認(rèn)大小限制是2M(2097152字節(jié)),也可以通過struts.properties文件中的struts.multipart.maxSize修改,如struts.multipart.maxSize=2048 表示一次上傳文件的總大小不能超過2K字節(jié)。
下面的代碼是上傳文件的JSP頁面代碼:
- < %@ page language="java" import="java.util.*" pageEncoding="GBK"%>
- < %@ taglib prefix="s" uri="/struts-tags"%>
- < html>
- < head>
- < title>上傳單個文件< /title>
- < /head>
- < body>
- < s:form action="upload" namespace="/test"
- enctype="multipart/form-data">
- < s:file name="upload" label="輸入要上傳的文件名" />
- < s:submit value="上傳" />
- < /s:form>
- < /body>
- < /html>
也可以在success.jsp頁中通過< s:property>獲得文件的屬性(文件名和文件內(nèi)容類型),代碼如下:
< s:property value="uploadFileName"/>
二、上傳任意多個文件
在Struts2中,上傳任意多個文件也非常容易實現(xiàn)。首先,要想上傳任意多個文件,需要在客戶端使用DOM技術(shù)生成任意多個< input type=”file” />標(biāo)簽。name屬性值都相同。代碼如下:
- < html>
- < head>
- < script language="javascript">
- function addComponent()
- {
- var uploadHTML = document.createElement( "< input type='file' name='upload'/>");
- document.getElementById("files").appendChild(uploadHTML);
- uploadHTML = document.createElement( "< p/>");
- document.getElementById("files").appendChild(uploadHTML);
- }
- < /script>
- < /head>
- < body>
- < input type="button" onclick="addComponent();" value="添加文件" />
- < br />
- < form onsubmit="return true;" action="/struts2/test/upload.action"
- method="post" enctype="multipart/form-data">
- < span id="files"> < input type='file' name='upload' />
- < p />
- < /span>
- < input type="submit" value="上傳" />
- < /form>
- < /body>
- < /html>
上面的javascript代碼可以生成任意多個< input type=’file’>標(biāo)簽,name的值都為file(要注意的是,上面的javascript代碼只適合于IE瀏覽器,firefox等其他瀏覽器需要使用他的代碼)。至于Action類,和上傳單個文件的Action類基本一至,只需要將三個屬性的類型改為List即可。代碼如下:
- package action;
- import java.io.*;
- import com.opensymphony.xwork2.ActionSupport;
- public class UploadMoreAction extends ActionSupport
- {
- private java.util.List< File> uploads;
- private java.util.List< String> fileNames;
- private java.util.List< String> uploadContentTypes;
- public java.util.List< String> getUploadFileName()
- {
- return fileNames;
- }
- public void setUploadFileName(java.util.List< String> fileNames)
- {
- this.fileNames = fileNames;
- }
- public java.util.List< File> getUpload()
- {
- return uploads;
- }
- public void setUpload(java.util.List< File> uploads)
- {
- this.uploads = uploads;
- }
- public void setUploadContentType(java.util.List< String> contentTypes)
- {
- this.uploadContentTypes = contentTypes;
- }
- public java.util.List< String> getUploadContentType()
- {
- return this.uploadContentTypes;
- }
- public String execute() throws Exception
- {
- if (uploads != null)
- {
- int i = 0;
- for (; i < uploads.size(); i++)
- {
- java.io.InputStream is = new java.io.FileInputStream(uploads.get(i));
- java.io.OutputStream os = new java.io.FileOutputStream(
- "d:\\upload\\" + fileNames.get(i));
- byte buffer[] = new byte[8192];
- int count = 0;
- while ((count = is.read(buffer)) > 0)
- {
- os.write(buffer, 0, count);
- }
- os.close();
- is.close();
- }
- }
- return SUCCESS;
- }
- }
在execute方法中,只是對List對象進(jìn)行枚舉,在循環(huán)中的代碼和上傳單個文件時的代碼基本相同。如果讀者使用過struts1.x的上傳組件,是不是感覺Struts2的上傳功能更容易實現(xiàn)呢?在Struts1.x中上傳多個文件時,可是需要建立帶索引的屬性的。而在Struts2中,就是這么簡單就搞定了。圖1是上傳任意多個文件的界面。
圖1
【編輯推薦】