您的位置:首页 > 编程语言 > Java开发

struts2.0实现文件上传

2012-03-07 11:05 483 查看
首先,引入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 {

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 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结果,否则发生问题的时候找不到跳转目标。

上面的例子是我测试通过了的。当然,文件上传还有一些尾巴工作可以改进,比如文件存储的临时路径、错 误提示信息的国际化等等。这些另外再说吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: