Struts2文件上传

文件上传是Web应用经常需要面对的问题,下面是我总结的Struts2的文件上传相关知识,以便自己以后查看使用。
表单元素的enctype属性
表单的enctype属性指定的是表单数据的编码方式,该属性有如下三个值
1、application/x-www-form-urlencoded这是默认的编码方式,它只处理表单域里的value属性值。采用这种编码方式的表单会将表单域的值处理成URL编码方式。
2、multipart/form-data这种编码方式会以二进制流的方式来处理表单数据。这种编码方式会把文件域指定文件的内容也封装到请求参数里。
3、text/plain当表单的action属性为matilto:URL的形式时使用这种编码方式比较方便,这种方式主要适用于直接通过表单发送邮件的情况。
Struts2的文件上传
Struts2并未提供自己的请求解析器,也就是说Struts2不会自己去处理multipart/form-data的请求,他需要调用其他上传组件来解析二进制请求数据。但Struts2在原有的上传解析器基础上做了进一步封装,进一步简化了文件上传。
Struts2默认使用的是Jakarta的Common-FileUpload文件上传框架,因此,如果需要使用Struts2的文件上传功能,则需要在Web应用中增加两个JAR文件,即commons-io-1.3.2.jarcommons-fileupload-1.2.1.jar
文件上传页面
<body>
	<s:fielderror />
	<form action="uploadPro" method="post" enctype="multipart/form-data">
		文件标题:<input type="text" name="title" /><br /> 
		选择文件:<input type="file" name="upload" /><br /> 
		<input type="submit" value="上传" />
	</form>
</body>
处理上传请求的Action类
package com.test.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.UUID;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport{
	//封装文件标题请求参数的属性
	private String title;
	//封装上传文件域的属性
	private File upload;
	//封装上传文件名的属性
	private String uploadContentType;
	//封装上传文件名的属性
	private String uploadFileName;
	//直接在struts.xml文件中配置的属性
	private String savePath;
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public File getUpload() {
		return upload;
	}
	public void setUpload(File upload) {
		this.upload = upload;
	}
	public String getUploadContentType() {
		return uploadContentType;
	}
	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	public String getUploadFileName() {
		return uploadFileName;
	}
	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	//返回上传文件的保存位置
	public String getSavePath() {
		return ServletActionContext.getRequest().getRealPath(savePath);
	}
	//接受struts.xml文件配置的方法
	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}
	@Override
	public String execute() throws Exception {
		String newName=UUID.randomUUID()+uploadFileName.substring(uploadFileName.lastIndexOf("."));
		//以服务器的文件保存地址和随机文件名建立上传文件输出流
		FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+newName);
		FileInputStream fis=new FileInputStream(getUpload());
		byte[] buffer=new byte[1024];
		int len=0;
		while((len=fis.read(buffer))>0){
			fos.write(buffer, 0, len);
		}
		setUploadFileName(newName);
		return SUCCESS;
	}
}
上面的Action除了与表单对应的upload和title两个属性外还包含了uploadFileName和uploadContentType两个属性,这两个属性分别用于封装上传文件的文件名、上传文件的文件类型。这是Struts2的独特之处,Action类通过File类型属性直接封装了上传文件的文件内容,但这个File属性无法获取上传文件的文件名和文件类型,所以Struts2直接将文件域中包含的上传文件名和文件类型的信息封装到uploadFileName和uploadContentType属性中。可以认为:如果表单包含一个name属性为XXX的文件域,则对应的Action需要使用三个属性类封装该文件域的信息。
1、类型为File的xxx属性封装了该文件域对应的文件内容
2、类型为String的xxxFileName属性封装了该文件域对应的文件的文件名
3、类型为String的xxxContentType属性封装了该文件域对应的文件的文件类型
通过上面的三个属性可以简单地实现文件上传,所以在execute方法中,可以直接通过调用getXXX()方法来获取上传文件的文件名、文件类型和文件内容。
上面的Action类还包含了一个savePath属性,该属性的值通过配置文件来动态设置,这是Struts2设计中一个典型的依赖注入。
配置文件上传的Action
<!-- 配置处理文件上传的Action -->
<action name="uploadPro" class="com.test.action.UploadAction">
    <!-- 动态设置Action的属性值 -->
    <param name="savePath">upload</param>
    <!-- 配置上传成功的视图页面 -->
    <result>succ.jsp</result>
</action>
上传成功页面
<body>
	上传成功!
	<br />
	<!-- 输出上传的表单里的文件标题属性 -->
	文件标题:
	<s:property value="+title" />
	<br />
	<!-- 根据上传文件的文件名,在页面上显示上传的图片 -->
	文件为:
	<img src='upload/<s:property value="uploadFileName"/>' />
	<br />
</body>
调试运行前在WebRoot下新建一个upload文件夹,用于存放上传文件。
运行结果:

拦截器实现文件过滤
Struts2提供了一个文件上传的拦截器,通过配置该拦截器可以更轻松地实现文件过滤,Struts2中文件上传的拦截器是fileUpload,为了让该拦截器起作用,只需要在该Action中配置该拦截器引用即可。
配置fileUpload拦截器时,可以为其指定两个参数。
1、allowedTypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开
2、maximunSize:该参数指定允许上传的文件的大小,单位是字节
通过配置fileUpload拦截器,可以更轻松地实现文件过滤,当文件过滤失败后,系统自动转入input逻辑视图,因此必须为该Action配置名为input的逻辑视图。除此之外,还必须显示地为该Action配置defaultStack的拦截器引用。
struts.xml配置
<!-- 配置处理文件上传的Action -->
		<action name="uploadPro" class="com.test.action.UploadAction">
			<!-- 配置fileUpload拦截器 -->
			<interceptor-ref name="fileUpload">
				<!-- 配置允许上传的文件类型 -->
				<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg,image/pjpeg</param>
				<!-- 配置允许上传的文件大小 -->
				<param name="maximunSize">2000</param>
			</interceptor-ref>
			<!-- 配置系统默认的拦截器 -->
			<interceptor-ref name="defaultStack" />
			<!-- 动态设置Action的属性值 -->
			<param name="savePath">/upload</param>
			<!-- 配置上传成功的视图页面 -->
			<result>succ.jsp</result>
			<!-- 配置input逻辑视图对应的视图页面 -->
			<result name="input">upload.jsp</result>
		</action>
多文件上传
Struts2也可以很方便的实现多文件上传。
文件上传页面
<body>
	<s:fielderror />
	<form action="uploadPro" method="post" enctype="multipart/form-data">
		文件标题:<input type="text" name="title" /><br /> 
		选择第一个文件:<input type="file" name="upload" /><br /> 
		选择第二个文件:<input type="file" name="upload" /><br /> 
		选择第三个文件:<input type="file" name="upload" /><br />
		<input type="submit" value="上传" />
	</form>
</body>
处理请求的Action类代码
package com.test.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.UUID;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport{
	//封装文件标题请求参数的属性
	private String title;
	//使用字符串数组封装多个文件域对应的文件内容
	private File[] upload;
	//使用字符串数组封装多个文件域对应的文件类型
	private String[] uploadContentType;
	//使用字符串数组封装多个文件域对应的文件名
	private String[] uploadFileName;
	//接受依赖注入的属性
	private String savePath;

	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public File[] getUpload() {
		return upload;
	}
	public void setUpload(File[] upload) {
		this.upload = upload;
	}
	public String[] getUploadContentType() {
		return uploadContentType;
	}
	public void setUploadContentType(String[] uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	public String[] getUploadFileName() {
		return uploadFileName;
	}
	public void setUploadFileName(String[] uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	//返回上传文件的保存位置
	public String getSavePath() {
		return ServletActionContext.getRequest().getRealPath(savePath);
	}
	//接受struts.xml文件配置的方法
	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}
	@Override
	public String execute() throws Exception {
		//取得需要上传的文件数组
		File[] files=getUpload();
		//遍历每个需要上传的文件
		for(int i=0;i<files.length;i++){
			String newName=UUID.randomUUID()+uploadFileName[i].substring(uploadFileName[i].lastIndexOf("."));
			//以服务器的文件保存地址和随机文件名建立上传文件输出流
			FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+newName);
			//以每个需要上传的文件建立文件输入流
			FileInputStream fis=new FileInputStream(files[i]);
			//将每个需要上传的文件写到服务器对应的文件中
			byte[] buffer=new byte[1024];
			int len=0;
			while((len=fis.read(buffer))>0){
				fos.write(buffer, 0, len);
			}
			fos.close();
			getUploadFileName()[i]=newName;
		}
		return SUCCESS;
	}
}
上传成功视图页面
<body>
	上传成功!
	<br />
	<!-- 输出上传的表单里的文件标题属性 -->
	文件标题:
	<s:property value="title" />
	<br />
	<!-- 根据上传文件的文件名,在页面上显示上传的图片 -->
	文件为:
	<s:iterator value="uploadFileName" id="fileName">
		<img src='upload/<s:property value="fileName"/>'
			style="width:50px;height:50px" />
	</s:iterator>
	<br />
</body>
结果展示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值