Struts 是通過Commons FileUpload文件上傳Commons FileUpload通過將HTTP的數據保存到臨時文件夾然後Struts使用fileUpload攔截器將文件綁定到Action的實例中從而我們就能夠以本地文件方式的操作浏覽器上傳的文件
具體實現
前段時間Apache發布了Struts GA所以本文的實現是以該版本的Struts作為框架的以下是例子所依賴類包的列表
清單 依賴類包的列表
首先創建文件上傳頁面FileUploadjsp內容如下
<% @ page language = java contentType = text/html; charset=utf pageEncoding = utf %>
<% @ taglib prefix = s uri = /strutstags %>
<! DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd >
< html xmlns = >
< head >
< title > Struts File Upload </ title >
</ head >
< body >
< s:form action =fileUpload method =POST enctype =multipart/formdata >
< s:file name =myFile label =Image File />
< s:textfield name =caption label =Caption />
< s:submit />
</ s:form >
</ body >
</ html >
清單
FileUpload
jsp
在FileUploadjsp中先將表單的提交方式設為POST然後將enctype設為multipart/formdata這並沒有什麼特別之處接下來<s:file/>標志將文件上傳控件綁定到Action的myFile屬性
其次是FileUploadActionjava代碼

package tutorial;


import java
io
BufferedInputStream;

import java
io
BufferedOutputStream;

import java
io
File;

import java
io
FileInputStream;

import java
io
FileOutputStream;

import java
io
InputStream;

import java
io
OutputStream;

import java
util
Date;


import org
apache
struts
ServletActionContext;


import com
opensymphony
xwork
ActionSupport;



public class FileUploadAction extends ActionSupport

{

private static final long serialVersionUID =
l ;

private static final int BUFFER_SIZE =
*
;

private File myFile;

private String contentType;

private String fileName;

private String imageFileName;

private String caption;


public void setMyFileContentType(String contentType)

{

ntentType = contentType;

}


public void setMyFileFileName(String fileName)

{

this
fileName = fileName;

}


public void setMyFile(File myFile)

{

this
myFile = myFile;

}


public String getImageFileName()

{

return imageFileName;

}


public String getCaption()

{

return caption;

}

public void setCaption(String caption)

{

this
caption = caption;

}


private static void copy(File src
File dst)

{


try

{

InputStream in = null ;

OutputStream out = null ;


try

{

in = new BufferedInputStream( new FileInputStream(src)
BUFFER_SIZE);

out = new BufferedOutputStream( new FileOutputStream(dst)
BUFFER_SIZE);

byte [] buffer = new byte [BUFFER_SIZE];


while (in
read(buffer) >
)

{

out
write(buffer);

}

} finally

{


if ( null != in)

{

in
close();

}

if ( null != out)

{

out
close();

}

}

} catch (Exception e)

{

e
printStackTrace();

}

}


private static String getExtention(String fileName)

{

int pos = fileName
lastIndexOf(
);

return fileName
substring(pos);

}

@Override


public String execute()

{

imageFileName = new Date()
getTime() + getExtention(fileName);

File imageFile = new File(ServletActionContext
getServletContext()
getRealPath(
/UploadImages
) +
/
+ imageFileName);

copy(myFile
imageFile);

return SUCCESS;

}

} 清單
tutorial/FileUploadAction
java
在FileUploadAction中我分別寫了setMyFileContentTypesetMyFileFileNamesetMyFile和setCaption四個Setter方法後兩者很容易明白分別對應FileUploadjsp中的<s:file/>和<s:textfield/>標志但是前兩者並沒有顯式地與任何的頁面標志綁定那麼它們的值又是從何而來的呢?其實<s:file/>標志不僅僅是綁定到myFile還有myFileContentType(上傳文件的MIME類型)和myFileFileName(上傳文件的文件名該文件名不包括文件的路徑)因此<s:file name=xxx />對應Action類裡面的xxxxxxContentType和xxxFileName三個屬性
FileUploadAction作用是將浏覽器上傳的文件拷貝到WEB應用程序的UploadImages文件夾下新文件的名稱是由系統時間與上傳文件的後綴組成該名稱將被賦給imageFileName屬性以便上傳成功的跳轉頁面使用
下面我們就來看看上傳成功的頁面
<% @ page language =
java
contentType =
text/html; charset=utf
pageEncoding =
utf
%>
<% @ taglib prefix =
s
uri =
/struts
tags
%>
<! DOCTYPE html PUBLIC
//W
C//DTD XHTML
Transitional//EN
transitional
dtd
>
< html xmlns =
>
< head >
< title > Struts
File Upload </ title >
</ head >
< body >
< div style =
padding:
px; border: solid
px #cccccc; text
align: center
>
< img src =
UploadImages/<s:property value =
imageFileName
/>
/>
< br />
< s:property value =
caption
/>
</ div >
</ body >
</ html > 清單
ShowUpload
jsp
ShowUploadjsp獲得imageFileName將其UploadImages組成URL從而將上傳的圖像顯示出來
然後是Action的配置文件
<? xml version=
encoding=
UTF
?>
<! DOCTYPE struts PUBLIC
//Apache Software Foundation//DTD Struts Configuration
//EN
dtd
>
< struts >
< package name =
fileUploadDemo
extends =
struts
default
>
< action name =
fileUpload
class =
tutorial
FileUploadAction
>
< interceptor
ref name =
fileUploadStack
/>
< result name =
success
> /ShowUpload
jsp </ result >
</ action >
</ package >
</ struts > 清單
struts
xml
fileUpload Action顯式地應用fileUploadStack的攔截器
最後是webxml配置文件
<? xml version=
encoding=
UTF
?>
< web
app id =
WebApp_
version =
xmlns =
xmlns:xsi =
instance
xsi:schemaLocation =
app_
_
xsd
>
< display
name > Struts
Fileupload </ display
name >
< filter >
< filter
name > struts
cleanup </ filter
name >
< filter
class >
org
apache
struts
dispatcher
ActionContextCleanUp
</ filter
class >
</ filter >
< filter >
< filter
name > struts
</ filter
name >
< filter
class >
org
apache
struts
dispatcher
FilterDispatcher
</ filter
class >
</ filter >
< filter
mapping >
< filter
name > struts
cleanup </ filter
name >
< url
pattern > /* </ url
pattern >
</ filter
mapping >
< filter
mapping >
< filter
name > struts
</ filter
name >
< url
pattern > /* </ url
pattern >
</ filter
mapping >
< welcome
file
list >
< welcome
file > l </ welcome
file >
</ welcome
file
list >
</ web
app > 清單
WEB
INF/web
xml
發布運行應用程序在浏覽器地址欄中鍵入出現圖示頁面
清單 FileUpload頁面
選擇圖片文件填寫Caption並按下Submit按鈕提交出現圖示頁面
清單 上傳成功頁面
更多配置
在運行上述例子如果您留心一點的話應該會發現服務器控制台有如下輸出
Mar
:
:
PM org
apache
struts
dispatcher
Dispatcher getSaveDir
INFO: Unable to find
struts
multipart
saveDir
property setting
Defaulting to ntext
tempdir
Mar
:
:
PM org
apache
struts
interceptor
FileUploadInterceptor intercept
INFO: Removing file myFile C:\Program Files\Tomcat
\work\Catalina\localhost\Struts
_Fileupload\upload_
c
_
e
__
ff
_
tmp 清單
服務器控制台輸出
上述信息告訴我們strutsmultipartsaveDir沒有配置strutsmultipartsaveDir用於指定存放臨時文件的文件夾該配置寫在strutsproperties文件中例如如果在strutsproperties文件加入如下代碼
struts
multipart
saveDir = /tmp 清單
struts配置
這樣上傳的文件就會臨時保存到你根目錄下的tmp文件夾中(一般為c:\tmp)如果此文件夾不存在Struts 會自動創建一個
錯誤處理
上述例子實現的圖片上傳的功能所以應該阻止用戶上傳非圖片類型的文件在Struts 中如何實現這點呢?其實這也很簡單對上述例子作如下修改即可
首先修改FileUploadjsp在<body>與<s:form>之間加入<s:fielderror />用於在頁面上輸出錯誤信息
然後修改strutsxml文件將Action fileUpload的定義改為如下所示
< action name =
fileUpload
class =
tutorial
FileUploadAction
>
< interceptor
ref name =
fileUpload
>
< param name =
allowedTypes
>
image/bmp
image/png
image/gif
image/jpeg
</ param >
</ interceptor
ref >
< interceptor
ref name =
defaultStack
/>
< result name =
input
> /FileUpload
jsp </ result >
< result name =
success
> /ShowUpload
jsp </ result >
</ action > 清單
修改後的配置文件
顯而易見起作用就是fileUpload攔截器的allowTypes參數另外配置還引入defaultStack它會幫我們添加驗證等功能所以在出錯之後會跳轉到名稱為input的結果也即是FileUploadjsp
發布運行應用程序出錯時頁面如下圖所示
清單 出錯提示頁面
上面的出錯提示是Struts 默認的大多數情況下我們都需要自定義和國際化這些信息通過在全局的國際資源文件中加入ntenttypenotallowed=The file you uploaded is not a image可以實現以上提及的需求對此有疑問的朋友可以參考我之前的文章《在Struts 中國際化(in)您的應用程序》
實現之後的出錯頁面如下圖所示
清單 自定義出錯提示頁面
同樣的做法你可以使用參數maximumSize來限制上傳文件的大小它對應的字符資源名為ssageserrorfiletoolarge
字符資源ssageserroruploading用提示一般的上傳出錯信息
多文件上傳
與單文件上傳相似Struts 實現多文件上傳也很簡單你可以將多個<s:file />綁定Action的數組或列表如下例所示
< s:form action =
doMultipleUploadUsingList
method =
POST
enctype =
multipart/form
data
>
< s:file label =
File (
)
name =
upload
/>
< s:file label =
File (
)
name =
upload
/>
< s:file label =
FIle (
)
name =
upload
/>
< s:submit />
</ s:form > 清單
多文件上傳JSP代碼片段
如果你希望綁定到數組Action的代碼應類似

private File[] uploads;

private String[] uploadFileNames;

private String[] uploadContentTypes;



public File[] getUpload()

{ return this
uploads; }

public void setUpload(File[] upload)

{ this
uploads = upload; }

public String[] getUploadFileName()

{ return this
uploadFileNames; }

public void setUploadFileName(String[] uploadFileName)

{ this
uploadFileNames = uploadFileName; }

public String[] getUploadContentType()

{ return this
uploadContentTypes; }

public void setUploadContentType(String[] uploadContentType)

{ this
uploadContentTypes = uploadContentType; } 清單
多文件上傳數組綁定Action代碼片段
如果你想綁定到列表則應類似

private List < File > uploads = new ArrayList < File > ();

private List < String > uploadFileNames = new ArrayList < String > ();

private List < String > uploadContentTypes = new ArrayList < String > ();



public List < File > getUpload()

{

return this
uploads;

}

public void setUpload(List < File > uploads)

{

this
uploads = uploads;

}

public List < String > getUploadFileName()

{

return this
uploadFileNames;

}

public void setUploadFileName(List < String > uploadFileNames)

{

this
uploadFileNames = uploadFileNames;

}

public List < String > getUploadContentType()

{

return this
uploadContentTypes;

}

public void setUploadContentType(List < String > contentTypes)

{

this
uploadContentTypes = contentTypes;

} 清單
多文件上傳列表綁定Action代碼片段
總結
在Struts 中實現文件上傳的確是輕而易舉您要做的只是使用<s:file />與Action的屬性綁定這又一次有力地證明了Struts 的簡單易用
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28217.html