上傳與下載,一個古老而現代的話題......讓我們試目以待
13.Struts2中文件的上傳與下載
(1). 數據編碼方式
表單的enctype屬性用於指定表單數據的編碼方式,它可以爲以下值:
l application/x-www-form-urlencoded:默認的編碼方式,只處理表單域裏的value屬性值,採用這種編碼方式的表單會將表單域的值處理成URL編碼方式。
l multipart/form-data:以二進制流的方式來處理表單數據,這種編碼方式會把文件域指定文件的內容也封裝到請求參數裏;
l text/plain:主要適用於直接通過表單發送郵件的方式。
爲了實現文件上傳功能,必須將form的enctype屬性值設置爲multipart/form-data類型。
(2). 上傳框架
Struts2默認使用Jakarta的Common-Fileupload組件來進行文件上傳操作,除了使用common-fileupload組件外,也可以使用其它的上傳組件,使用其它的組件時需要對struts.multipart.parser屬性進行配置,如下:
struts.multipart.parser = jakarta // 使用common-fileupload組件上傳
struts.multipart.parser = cost // 使用cos組件上傳
struts.multipart.parser = pell // 使用pell組件上傳
Common-Fileupload組件不管是文件域還是普通表單域,都把它當成FileItem對象來處理,如果該對象的isFormField()方法返回true,表明該表單域是一個普通表單域,否則將是一個文件域。以下給出幾個FileItem常用的方法:
l getFiledName():取得該表單域的name屬性值;
l getString(String encoding):取得該表單域的value屬性值,其中encoding參數設置編碼集;
l getName():僅當該表單域是文件域時才起作用,該方法返回上傳文件的文件名;
l getContentType():僅當該表單域是文件域時才起作用,該方法返回上傳文件的文件類型;
l get():僅當該表單域是文件域時才起作用,該方法返回上傳文件的文件內容字節;
l getInputStream():僅當該表單域是文件域時才起作用,該方法返回上傳文件對應的輸入流。
COS框架是oreilly組織下的一個小項目,與Common-Fileupload相比而言,COS在處理上傳下載時更加方便,COS用Part實例代表所有的表單域,不管是普通表單域還是文件域,都是Part實例;Part類有兩個子類:ParamPart和FilePart,分別代表普通表單域和文件域,以下爲Part類包含的常用方法:
l getName():取得該表單域的name屬性值;
ParamPart類常用方法:
l getStringValue(String encoding):取得該表單域的value屬性值,其中encoding參數設置編碼集;
FilePar類常用方法:
l getFileName():該方法返回上傳文件的文件名;
l getFilePath():該方法返回上傳文件的文件路徑;
l getContentType():該方法返回上傳文件的文件類型;
Struts2中無論使用Common-fileupload還是COS,對於文件上傳下載的操作都是一樣的,在Struts2中,使用File類來封裝文件域,如果表單中包含一個name屬性爲xxx的文件域,則對應的Action需要使用3個屬性來封裝該文件域的信息:
l 類型爲File的xxx屬性:封裝文件域對應的文件內容;
l 類型爲String的xxxFileName屬性:封裝該文件域對應的文件的文件名;
l 類型爲String的xxxContentType屬性:封裝該文件域對應的文件的文件類型。
(3). 實現文件過濾
在Struts2中除了手動實現文件過濾操作外,還可以使用Struts2提供的上傳文件過濾器fileUpload,配置fileUpload時需要指定兩個參數:
l allowedTypes:指定允許上傳的文件類型,多個文件類型之間用英文逗號隔開;
l maximumSize:指定允許上傳的文件大小,單位是字節
需要說明的是,當文件過濾失效後,會自動轉入input邏輯視圖,除此之外還必須顯示地爲該Action配置defaultStack的攔截器起用,示例如下:
<package name=”demo” extends=”struts-default.xml”>
<action name=”upload” class=”com.demo.UploadAction”>
<interceptor-ref name=”fileUpload”>
<param name=”allowedTypes”>bmp, jpg, png</param>
<param name=”maximumSize”>2000</param>
</interceptor-ref>
<interceptor-ref name=”defaultStack” />
<param name=”savePath”>/uploadDir</param>
<result name=”error”>/error.jsp</result>
<result name=”input”>/input.jsp</result>
<result>/success.jsp</result>
</action>
</package>
上傳文件太大的提示信息的key 爲:struts.messages.error.file.too.large
上傳文件時文件類型是不允許上傳的文件類型時的消息key爲:
struts.messages.error.content.type.not.allowed
未知的錯誤的提示信息key爲:struts.messages.error.uploading
爲了避免使用WEB容器的工作路徑作爲臨時路徑,需要設置struts.multipart.saveDir屬性;此外整個表單請求內容的最大字節數由屬性struts.multipart.maxSize設置。
(4). 文件下載
Struts2的文件下載Action需要提供一個返回InputStream流的方式,該輸入流代表了被下載文件的入口。
在配置Action方面,與配置普通的Actoin沒什麼區別,唯一不同的是需要額外加上download攔截器引用,配置時需要指定以下參數:
l contentType:指定被下載文件的文件類型;
l inputName:指定被下載文件的入口輸入流;
l contentDisposition:指定下載的文件名;
l bufferSize:指定下載文件時的緩衝大小。
示例:
public class DownloadDemo{
……
public InputStream getDownloadFile() throws Exception{
return ServletActionContext.getServletContext().getResourceAsStream(inputPath));
}
……
}
struts.xml
<package name=”demo” extends=”struts-default.xml”>
<default-action-ref name=”download”/>
<action name=”download” class=”com.demo.DownloadAction”>
<result type=”stream” name=”successs”>
<param name=”contenType”>/image/gif</param>
<param name=”inputName”>downloadFile</param>
<param name=”contentDisposition”>filename=”struts.gif”</param>
<param name=”bufferSize”>4096</param>
</result>
</action>
</package>