首先,引入jar包。除了 Struts2.0的幾個核心jar包外,還需要額外引入commons-fileupload.jar和commons-io.jar。
引入這兩個包的時候,似乎版本也是一個比較重要的問題。我原先引入的是commons- fileupload-1.0.jar和commons-io.不知道那個版本.jar。代碼全部寫好之後卻報 java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]。這個class是在Struts1.0-core.jar包裡的,卻死活找不到。直到我把兩個包更新到了更高的版本,才算解決了這個 怪異的問題。
引入了jar包之後,寫action的代碼。主要的代碼來自網絡。可以忽略其中的log、 errorbean、baseaction等我自己寫的東西。
package common.web.action;
import java.io.*;
import java.util.Date;
import org.apache.struts2.ServletActionContext;
/**
* 實作檔案上傳的action
*
*/
public class UploadAction extends BasicAction {
private static final long serialVersionUID = 572146812454l;
// 輸入、輸出流的緩沖區大小
private int BUFFER_SIZE;
// 上傳檔案存儲路徑
private String filePath;
// 上傳檔案
// 注意,檔案上傳時<s:file/>同時與myFile,myFileContentType,myFileFileName綁定
// 是以同時要提供myFileContentType,myFileFileName的set方法
private File myFile;
// 上傳檔案類型
private String contentType;
// 上傳檔案名
private String fileName;
private String imageFileName;
// 檔案說明,與頁面屬性綁定
private String caption;
* 主要的方法,從請求中讀取檔案,複制到指定的路徑下去
@Override
public String execute() {
log.info("上傳的檔案資訊:");
log.info("檔案名: " + fileName+"; 檔案類型: " + contentType+"; 檔案大小: " + myFile.length() + " bytes");
// 利用目前時間的毫秒數,加上原檔案的擴充名,構成新的檔案名
imageFileName = new Date().getTime() + getExtention(fileName);
log.info("新的檔案名為= " + imageFileName);
log.info("新的檔案存儲路徑為= " + this.filePath);
File imageFile;
try {
// 如果是絕對路徑
if (filePath.indexOf(":") > 0) {
imageFile = new File(this.filePath + "/" + imageFileName);
} else {
// 在工程路徑下的檔案夾中,根據新的檔案名,建立檔案
imageFile = new File(ServletActionContext.getServletContext()
.getRealPath(this.filePath)
+ "/" + imageFileName);
}
} catch (NullPointerException e) {
e.printStackTrace();
errorbean.setErrorMessage("找不到上傳檔案的儲存路徑!");
errorbean.setMyException(e);
errorbean.setSuccess(false);
log.error(errorbean.toString());
return INPUT;
}
// 将請求中的檔案複制到新的檔案中
save(myFile, imageFile);
errorbean.setSuccess(true);
errorbean.setErrorMessage("檔案上傳成功!");
if (errorbean.isSuccess()) {
return SUCCESS;
} else {
}
* 将請求中的檔案複制到指定路徑下去的方法;
* @param File
* src: 源檔案
* det: 目标檔案
private void save(File src, File dst) {
// 輸入輸出流
InputStream in = null;
OutputStream out = null;
// 根據源檔案和緩沖區大小,建立輸入流
in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
} catch (Exception e) {
errorbean.setErrorMessage("無法建立輸入流!");
return;
// 根據目标檔案和緩沖區大小,建立輸出流
out = new BufferedOutputStream(new FileOutputStream(dst),
BUFFER_SIZE);
errorbean.setErrorMessage("無法建立輸出流!");
}
// 從輸入流中讀取檔案,寫入輸出流中
byte[] buffer = new byte[BUFFER_SIZE];
while (in.read(buffer) > 0) {
out.write(buffer);
} catch (IOException e) {
errorbean.setErrorMessage("從輸入流中讀取/向輸出流中寫入資料時發生異常!");
} finally {
try {
// 關閉輸入輸出流
if (null != in) {
in.close();
}
if (null != out) {
out.close();
} catch (IOException e) {
e.printStackTrace();
* 擷取上傳檔案擴充名的方法
* @param String
* fileName:上傳檔案的全名
* @return String: 上傳檔案的擴充名
private String getExtention(String fileName) {
int pos = fileName.lastIndexOf(".");
return fileName.substring(pos);
* getter & setter
public void setMyFileContentType(String contentType) {
this.contentType = contentType;
public void setMyFileFileName(String fileName) {
this.fileName = fileName;
public void setMyFile(File myFile) {
this.myFile = myFile;
public void setMyFile(String myFile) {
System.out.println("String 類型的 myFile: "+myFile);
public String getImageFileName() {
return imageFileName;
public String getCaption() {
return caption;
public void setCaption(String caption) {
this.caption = caption;
public void setBUFFER_SIZE(int buffer_size) {
BUFFER_SIZE = buffer_size;
public int getBUFFER_SIZE() {
return BUFFER_SIZE;
public void setFilePath(String filePath) {
this.filePath = filePath;
jsp頁面的寫法如下。 <body>
This is my JSP page for upload file.
<br>
<s:property value="errorbean.errorMessage"/>
<s:form action="fileupload" namespace="/" method="POST" enctype="multipart/form-data">
<s:file name="myFile" label="MyFile"></s:file>
<s:textfield name="caption" label="Caption"></s:textfield>
<s:submit label="submit"></s:submit>
</s:form>
</body>
其中,enctype="multipart/form-data"是上傳檔案的form的寫法。如 果不這樣寫,action無法在Request裡面找到對應的file。并且,寫了這個東西最好配置上namespace。我最初隻寫 enctype="multipart/form-data"而沒寫namespace,結果又報 java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]。這個東西真是陰魂不散!不過加了namespace之後就沒事了。
struts.xml:
<action name="fileupload" class="UPLOAD">
<interceptor-ref name="fileUpload">
<param name="maximumSize">4194304</param>
<param name="allowedTypes">
image/jpeg,image/gif,image/jpg
</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result name="success">test/upload.jsp</result>
<result name="input">test/upload.jsp</result>
</action>
Struts.xml裡面的<interceptor-ref name="fileUpload">是為了限制上傳檔案的大小和檔案類型做的配置,配置的内容就是下面的兩個<param>标簽。在 這個過濾器之後一定要加上<interceptor-ref name="defaultStack" />,否則fileupload過濾到問題之後,不會轉到input結果中去,而仍然會向action中跳轉。這時讀取到的file就是null 了。此外,配置了這倆過濾器,就必須配置input結果,否則發生問題的時候找不到跳轉目标。
上面的例子是我測試通過了的。當然,檔案上傳還有一些尾巴工作可以改進,比如檔案存儲的臨時路徑、錯 誤提示資訊的國際化等等。這些另外再說吧!
本文轉自 斯然在天邊 51CTO部落格,原文連結:http://blog.51cto.com/winters1224/799053,如需轉載請自行聯系原作者