首先,引入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;
// 上传文件
// 注意,文件上传时
// 所以同时要提供myFileContentType,myFileFileName的set方法
private File myFile;
// 上传文件类型
private String contentType;
// 上传文件名
private String fileName;
private String p_w_picpathFileName;
// 文件说明,与页面属性绑定
private String caption;
/**
* 主要的方法,从请求中读取文件,复制到指定的路径下去
*/
@Override
public String execute() {
log.info("上传的文件信息:");
log.info("文件名: " + fileName+"; 文件类型: " + contentType+"; 文件大小: " + myFile.length() + " bytes");
// 利用当前时间的毫秒数,加上原文件的扩展名,构成新的文件名
p_w_picpathFileName = new Date().getTime() + getExtention(fileName);
log.info("新的文件名为= " + p_w_picpathFileName);
log.info("新的文件存储路径为= " + this.filePath);
File p_w_picpathFile;
try {
// 如果是绝对路径
if (filePath.indexOf(":") > 0) {
p_w_picpathFile = new File(this.filePath + "/" + p_w_picpathFileName);
} else {
// 在工程路径下的文件夹中,根据新的文件名,创建文件
p_w_picpathFile = new File(ServletActionContext.getServletContext()
.getRealPath(this.filePath)
+ "/" + p_w_picpathFileName);
}
} catch (NullPointerException e) {
e.printStackTrace();
errorbean.setErrorMessage("找不到上传文件的保存路径!");
errorbean.setMyException(e);
errorbean.setSuccess(false);
log.error(errorbean.toString());
return INPUT;
}
// 将请求中的文件复制到新的文件中
save(myFile, p_w_picpathFile);
errorbean.setSuccess(true);
errorbean.setErrorMessage("文件上传成功!");
if (errorbean.isSuccess()) {
return SUCCESS;
} else {
return INPUT;
}
}
/**
* 将请求中的文件复制到指定路径下去的方法;
*
* @param File
* src: 源文件
* @param File
* det: 目标文件
*/
private void save(File src, File dst) {
// 输入输出流
InputStream in = null;
OutputStream out = null;
try {
// 根据源文件和缓冲区大小,创建输入流
in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
} catch (Exception e) {
e.printStackTrace();
errorbean.setErrorMessage("无法创建输入流!");
errorbean.setMyException(e);
errorbean.setSuccess(false);
log.error(errorbean.toString());
return;
}
try {
// 根据目标文件和缓冲区大小,创建输出流
out = new BufferedOutputStream(new FileOutputStream(dst),
BUFFER_SIZE);
} catch (Exception e) {
e.printStackTrace();
errorbean.setErrorMessage("无法创建输出流!");
errorbean.setMyException(e);
errorbean.setSuccess(false);
log.error(errorbean.toString());
return;
}
// 从输入流中读取文件,写入输出流中
byte[] buffer = new byte[BUFFER_SIZE];
try {
while (in.read(buffer) > 0) {
out.write(buffer);
}
} catch (IOException e) {
e.printStackTrace();
errorbean.setErrorMessage("从输入流中读取/向输出流中写入数据时发生异常!");
errorbean.setMyException(e);
errorbean.setSuccess(false);
log.error(errorbean.toString());
return;
} 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 p_w_picpathFileName;
}
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页面的写法如下。
This is my JSP page for upload file.
其中,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:
4194304
p_w_picpath/jpeg,p_w_picpath/gif,p_w_picpath/jpg
Struts.xml里面的
上面的例子是我测试通过了的。当然,文件上传还有一些尾巴工作可以改进,比如文件存储的临时路径、错 误提示信息的国际化等等。这些另外再说吧!