commons-fileupload-*.jar
commons-io-*.jar
2. 文件上传页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Struts2文件上传</title>
</head>
<body>
<s:form action="fileUpload" method="post" enctype="multipart/form-data">
<s:file name="image" label="添加图片"/>
<s:submit/>
</s:form>
</body>
</html>
3. FileUploadAction
package com.commons;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
public class FileUploadAction {
private File image;
private String imageContentType;
private String imageFileName;
//get、set方法略
private String generateFileName(String fileName) {
DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String formatDate = format.format(new Date());
int random = new Random().nextInt(10000); //[0,10000)
int position = fileName.lastIndexOf(".");
String extension = fileName.substring(position);
return formatDate + random + extension;
}
public String execute() throws Exception {
String targetDirectory = ServletActionContext.getServletContext().getRealPath("/upload/image");
File directory = new File(targetDirectory);
if(!directory.exists()){
directory.mkdirs();
}
String targetFileName = generateFileName(imageFileName);
File target = new File(targetDirectory, targetFileName);
FileUtils.copyFile(image, target);
return "success";
}
}
在FileUploadAction中我分别写了setImage、setImageContentType和setImageFileName三个Setter方法,第一个很容易明白,对应fileupload.jsp中的<s:file/>标签。但是后两者并没有显式地与任何的页面标签绑定,那么它们的值又是从何而来的呢?其实,<s:file/>标签不仅仅是绑定到image,还绑定imageContentType(上传文件的MIME类型)和imageFileName(上传文件的文件名,不包括文件的路径)。因此,<s:file name="xxx" />对应Action类里面的xxx、xxxContentType和xxxFileName三个属性。
4. struts.xml
<package name="Struts2_Upload" extends="struts-default" >
<action name="fileUpload" class="com.commons.FileUploadAction">
<result>/showupload.jsp</result >
</action>
</package>
5. 创建完结果页面showupload.jsp就可以运行本示例了。
在运行上述例子,如果您留心一点的话,应该会发现服务器控制台有如下输出:
四月 23, 2013 10:50:18 下午 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
四月 23, 2013 10:50:18 下午 com.opensymphony.xwork2.util.logging.commons.CommonsLogger warn
WARNING: Content-Type not allowed: image "张超的简历03.doc" "upload__4e70a7f8_13e375fb1ec__8000_00000000.tmp" application/octet-stream
四月 23, 2013 10:50:18 下午 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Removing file image E:\ide\apache-tomcat-7.0.32\work\Catalina\localhost\struts2_1\upload__4e70a7f8_13e375fb1ec__8000_00000000.tmp
上述信息告诉我们,struts.multipart.saveDir没有配置。struts.multipart.saveDir用于指定存放临时文件的文件夹,该配置写在struts.properties文件(在scr目录下)中。例如,在struts.properties文件加入如下代码:struts.multipart.saveDir=/tmp
6. 阻止用户上传非图片类型的文件:
在Struts 2中如何实现这点呢?其实这也很简单,对上述例子作如下修改即可。
首先修改fileupload.jsp,在<body>与<s:form>之间加入“<s:fielderror />”,用于在页面上输出错误信息。
然后让 FileUploadAction继承ActionSupport类。
再修改struts.xml文件,将FileUploadAction的定义改为如下所示:
<package name="Struts2_Upload" extends="struts-default">
<action name="fileUpload" class="com.commons.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>/showupload.jsp</result>
</action>
</package>
显而易见,起作用的就是fileUpload拦截器的allowTypes参数。另外,配置还引入defaultStack,它会帮我们添加验证等功能,所以在出错之后会跳转到名称为“input”的结果,也即是fileupload.jsp。
上面的出错提示是Struts 2默认的,大多数情况下,我们都需要自定义和国际化这些信息。通过在全局的国际资源文件中加入“struts.messages.error.content.type.not.allowed=The file you uploaded is not a image”,可以实现以上提及的需求。