文件上传的秘密(四)大小限制与进度

RFC1867规范中,对表单上传文件的大小和进度都没有作出规定,W3C的HTML规范的FileUpload对象(<input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建)也没有对表单中的文件大小作出限制,因此,这个问题还是留给了WEB应用服务器端开发人员。
HTTP请求提交到服务器端后,在未解析各boundary中的文件内容之前,是可以知道这次HTTP请求的总长度的,但是考虑到一个表单内可以容纳多个FileUpload对象,所以,只要发现解析的两个boundary内的字节数超过指定的数量,立即抛出一个运行期异常ThresholdException。重构后的的MultiPartFile类,增加了bytes和threshold成员变量,append方法中新增加3行代码,并且,其子类要显式调用super.append(…);


public void append(byte[] buff, int off, int len) throws IOException {
		bytes += len;
		if (threshold > 0 && bytes > threshold)
			throw new ThresholdException();
}


在开发中,如果程序代码未捕获这个运行期异常,上传文件的过程终止,如果捕获了此异常,并且未让程序终止,上传文件的过程继续,也就是虽然超出了大小限制,但仍然完成了文件上传的过程,文件会被保存到磁盘或者内存中。

对于文件上传的进度,RFC 1867也没有做相应的描述,从文件被编码到发送请求到服务器端,直至文件被解析出来并保存,是一个复杂的过程,RFC未对此做详细描述。浏览器对此功能有一些自主的空间,是先读取所有的文件再编码,还是逐个文件读取逐个编码,还是对文件进行局部编码局部发送,这些方式可以采用同步发送也可以采用异步。
这些复杂未描述的方式,对开发者来说,到底是什么相对于什么的进度,是非常迷惑的。在RFC 1867中,根本就是一个不予以考虑的问题,所以,文件上传的进度,是属于一个很含糊的需求。HTTP是无状态的协议,又缺少了客户端的支持,这个实现这个功能本身,需要不小的资源开销。用一个词来概括这个功能——鸡肋。
尽管如此,未了满足一些对网页特效的要求,FastUpload这个开源组件还是提供了进度的功能,但是,非常有限。只有在表单内仅有一个文件输入组件时才能生效,而且,这个进度受上传请求编码方式的影响,并不精确。

public class ProgressListener {
	
	private FileUploadParser fileUploadParser;
	
	public ProgressListener(FileUploadParser fileUploadParser) {
		super();
		this.fileUploadParser = fileUploadParser;
	}

	public double progress() {
		return fileUploadParser.getReadBytes()*1.0 / fileUploadParser.getContentLength();
	}

}


开发人员在需要了解文件上传进度的时候,才调用progress()函数。

<原创内容,版权所有,如若转载,请注明出处,不胜感谢!仪山湖>

猜你喜欢

转载自mojarra.iteye.com/blog/1542826