Struts文件上传

  • 相信文件上传功能是当下很多web程序必需品,Struts为我们提供了简单易用的文件上传功能。

基于传统Servlet的文件上传与使用Struts的文件上传比对

文件上传是通过表单来实现的,表单传递数据有两种形式,一种是以字符串的形式,另外一种是以二进制流的形式。当要在表单中传文件时,enctype就必须设置成为二进制流形式,即enctype="multipart/form-data"。这时表单中不单单是文件,还有其他的表单域也会以二进制流形式传递。传统的Servlet中,需要将文件从二进制流中分离出来,一般是通过设置一个不会被使用到的符号做标记来进行分离,这样文件上传的工作是比较繁琐的。庆幸的是Struts为我们提供了更简单易用的文件上传功能,让我们不用自己编写代码去从二进制数据流中分离出文件。

Sturts中的文件上传

在Struts中,文件上传会被划分为单文件上传和多文件上传,之所以会这么划分,是因为单文件上传和多文件上传时,Action的属性类型有所不同,所以需要区分对待,下面也会划分为单文件上传和多文件上传来讲。

首先文件上传是由动作来处理的,Struts要求我们在动作中具备以下的三个属性:

  • [inutName]
  • [inputName]FileName
  • [inputName]ContentType

其中inputName是表单中,文件上传域的name属性名称,比方说,你在表单中存在一个文件上传域<s:file name="file"/>,那么我们的动作中就必须具备file、fileFileName、fileContentType三个属性名称。

文件上传常量配置

文件上传时,我一般在struts.xml中配置两个常量

	<!-- 在配置文件中需要配置两个关于文件上传的常量 -->
	<constant name="struts.multipart.maxSize" value="104857600"></constant>
	<constant name="struts.multipart.saveDir" value="/tmpfiles"></constant>
其中名称为struts.multipart.maxSize常量是配置上传的所有文件总大小限制,这个常量的默认值是2MB,这里的计量单位是B。如果上传的文件大小超过了该常量值的大小,那么动作将会返回INPUT,execute方法不执行,并抛出一个SizeLimitExceededException,这时候,[inutName]、[inputName]FileName和[inputName]ContentType三个属性值都将null。

而名称为struts.mutipart.saveDir常量是配置上传文件时产生的临时文件(从客户端将文件传送到服务器是会产生临时文件的)的存放路径,相对的路径是web程序的根。

单文件上传

单个文件上传时,上述的三个属性所取的类型如下:

  • [inputName]:File
  • [inputName]FileName:String
  • [inputName]ContentType:String

当表单提交到动作后,会自动将属性填充进来,[inputName]是存放在服务器临时目录下的临时文件,所以千万不要使用[inputName].getName()来获取文件名,临时文件的名称是随机的,后缀是.tmp,但是它内部的数据是我们想要的数据。[inputName]FileName是上传的那个文件的文件名称,这个文件名称是带后缀的。[inputName]ContentType是上传的文件的MIME类型。

当属性填充完后,需要做的是将临时文件拷贝到服务器的某个路径下,在动作的execute方法中书写我们的业务逻辑就可以,以下是一个实例:

@SuppressWarnings("serial")
public class SingleUploadAction extends ActionSupport implements ServletContextAware {

	private File file; //取名为[inputName]
	
	private String fileFileName;	//取名为[inputName]Fileame
	
	private String fileContentType;	//取名为[inputName]ContentType
	
	private ServletContext context;

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	public String getFileContentType() {
		return fileContentType;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		/*
		 * 执行应该做的IO操作,将临时文件拷贝到应用程序根目录下的upload文件夹中,且文件名跟上传的文件同名
		 */
		if(fileFileName == null)
		{
			System.out.println(file);
			System.out.println(fileContentType);
			return INPUT;
		}
		File parent = new File(context.getRealPath("/upload"));
		if(parent.exists())
		{
			RandomAccessFile fileReader = new RandomAccessFile(file, "r");
			File dest = new File(parent, fileFileName);
			dest.createNewFile();
			RandomAccessFile fileWriter = new RandomAccessFile(dest, "rw");
			byte[] buffer = new byte[1024];
			int len = -1;
			while((len = fileReader.read(buffer)) != -1)
			{
				fileWriter.write(buffer, 0, len);
			}
			fileWriter.close();
			fileReader.close();
		}
		return SUCCESS;
	}

	public void setServletContext(ServletContext arg0) {
		// TODO Auto-generated method stub
		this.context = arg0;
	}
	
	
}

动作的配置

处理文件上传的Action要配置文件上传拦截器,以下是配置的实例:

		<action name="singleUpload" class="com.daniel.action.SingleUploadAction">
			<interceptor-ref name="fileUpload">
				<param name="allowedTypes">application/pdf</param>
			</interceptor-ref>
			<interceptor-ref name="basicStack"></interceptor-ref>
			<result name="success">/jsp/ListFile.jsp</result>
			<result name="input">/jsp/SingleUpload.jsp</result>
		</action>
其中参数allowedTypes是允许上传的文件类型,可以配置多个类型,用逗号隔开。

如果碰到不允许上传的文件类型,依旧会执行execute方法,而且动作中[inutName]、[inputName]FileName和[inputName]ContentType三个属性值都将null。

多文件上传

多文件上传时,上述的三个属性所取的类型如下:

  • [inputName]:File[] 或者List<File>
  • [inputName]FileName:String[]
  • [inputName]ContentType:String[]

单文件上传与多文件上传的异同

不同点:仅在于三个属性的类型不一样。

相同点:业务逻辑的编写、动作配置、运行机制。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值