Struts2框架默认使用了Common-fileUpload组件,该组件将解析出HttpservletRequest请求中的文件域信息,并使用IO数据流的方式,将文件保存在服务器的指定位置,完成文件
上传。
1、 Commons-IO是一个非常有用的IO工具包,主要包括下面3个方面:
Utility classes:提供静态方法来完成通用的任务。
Filters:提供丰富功能的文件过滤器。
Streams:执行reader和writer有用的Stream。
2、 文件上传的JSP页面
在JSP中,form标签的enctype属性应设置为multipart/form-data。
Form表单的enctype属性用来指定表单数据的编码方式,有如下3个:
application/x-www-form-urlencoded:如果指定该值,则表单中的数据被编码为Key-Value对,即默认的编码方式。
multipart/form-data:即使用mine编码,会以二进制流的方式来处理表单数据,文件上传需要使用该编码方式。
text/plain:表单数据以纯文本形式进行编码,其中不含任何控件或格式符。
3、 文件上传的Action
public class FileUploadAction extends ActionSupport {
private File doc;//封装上传文件的属性
private String fileName;//封装上传文件的名称属性
private String contentType;//封装上传文件的类型属性
private String dir;//保存文件路径属性
private String targetFileName;//保存文件名称属性
public void setDoc(File file) {
this.doc = file;
}
public void setDocFileName(String fileName) {
this.fileName = fileName;
}
public void setDocContentType(String contentType) {
this.contentType = contentType;
}
……省略部分getter和setter方法
public String execute() throws Exception{
String realPath = ServletActionContext.getRequest().getRealPath("/upload");
String targetDirectory=realPath;
targetFileName=generateFileName(fileName);//生成保存文件的名称
setDir(targetDirectory+"//"+targetFileName);//保存文件的路径
File target=new File(targetDirectory,targetFileName);//建立一个目标文件
FileUtils.copyFile(doc, target);//将临时文件复制到目标文件
return SUCCESS;
}
//为上传文件自动分配文件名称,避免重复
private String generateFileName(String fileName){
DateFormat format=new SimpleDateFormat("yyMMddHHmmss");
String formatDate=format.format(new Date());
int random=new Random().nextInt(10000);//随即生成文件编号
int position=fileName.lastIndexOf(".");//得到文件名中"."的位置
System.out.println(fileName);
System.out.println(position);
String extension=fileName.substring(position);//得到文件的扩展名
System.out.println(extension);
return formatDate+random+extension;
}
}
该Action中定义了一个File类型的doc属性,用来对应JSP中表单中文件域的name值。同时定义了两个非常重要的属性:fileName和contentType,这三个属性封装了文件上传的相关信息:
File类型的doc属性封装了该文件域对应的文件内容。
String类型的fileName属性封装了该文件域对应的文件名。
String类型的contentType属性封装了该文件域对应的文件类型。
注意: 实际上Action中是使用setter来封装文件域的3个参数的。如果该文件域name值
为xxx,则Action中使用setXxx()来封装File类型的文件内容;使用setXxxFileName()来
封装文件名称;使用setXxxContentType()来封装文件类型。只要Action定义了上面的3
个方法,就能够在execute()方法中获得相关信息。
最好在struts.properties中定义如下常量:
struts.multipart.saveDir= /tmp
这样上传的文件就会临时保存到服务器根目录下的tmp文件夹中,如果文件夹不存在,Struts2会自动创建一个。
4、 上传文件过滤
为了防止用户上传木马等病毒,需要限制上传文件的文件类型;为了防止服务器空间不足,需要限制用户上传文件的大小等。
Struts2框架内置了一个文件上传拦截器。该文件上传拦截器名称为fileUpload,只要在配置Action时引用该拦截器就可以实现相应的文件过滤。 以下为示例:
<action name="upload" class="fileUpLoad.FileUploadAction">
<interceptor-ref name="fileUpload">
<!—allowedTypes参数指定允许上传的文件类型 -->
<param name="allowedTypes">
text/plain, iamge/bmp,image/ppng,image/pjpeg,iamge/gif,image/pjpeg,image/tiff
</param>
<!—maximumSize 参数指定了上传文件的最大容量(单位字节)-->
<param name="maximumSize">10000000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/fileUpLoad/uploadSuccess.jsp</result>
<result name="input">/fileUpLoad/fileUpload.jsp</result>
</action>