1 引言
一个网站总是不可避免的要和用户进行信息的交互,倘若是从窗体传送一般的简单输入类型(例如:text、password、radio、checkbox、select等等)的信息到服务器端时,只要使用application/x-www-form-urlencoded的编码方式用session传递就可以了。但是当涉及到和用户之间的文件交换(包括上传和下载)时,就不是那么简单了。在上传文件到服务器时,必须要使用multipart/form-data的编码方式,并且不能直接使用request.getParameter()来取得。至于所使用的方法有很多种,比如:jspsmart公司的jspsmartupload组件,O`Rrilly公司的cos组件,Jakarta Apache公司的commonsFileUpload组件,JavaZoom的uploadbean组件,还有Struts组件中自带的org.apache.struts.upload类工具等等。下面就针对其中的三种解决方案(jspsmartupload、O`Reilly-cos、struts.upload)做一个简单的介绍和对比。<o:p></o:p>
2 O`Rrilly-Cos
Cos组件是O`Rrilly公司开发的,该组件免费,不定期增加新功能,开源。<o:p></o:p>
<v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id="_x0000_i1025" style="width: 414.75pt; height: 299.25pt;" type="#_x0000_t75"><v:imagedata o:title="cos" src="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg"></v:imagedata></v:shape>
图1 O`Rrilly-Cos
在Cos组件中,MultipartRequest类主要负责文件上传的处理。MultipartRequest有8个构造函数:<o:p></o:p>
1.Public MultipartRequest ( HttpServletRequest request, String saveDirectory,) throws IOException<o:p></o:p>
2.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize) throws IOException<o:p></o:p>
3.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize, FileRenamePolicy policy) throws IOException<o:p></o:p>
4.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize, String encoding) throws IOException<o:p></o:p>
5.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize, String encoding, FileRenamePolicy policy) throws IOException<o:p></o:p>
6.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, String encoding) throws IOException<o:p></o:p>
7.Public MultipartRequest ( HttpServletRequest request, String saveDirectory) throws IOException<o:p></o:p>
8.Public MultipartRequest ( HttpServletRequest request, String saveDirectory, int maxPostSize) throws IOException<o:p></o:p>
前6种构造函数都是用来专门处理HTTP协议的,saveDirectory是上传文件要存储在服务器端的目录名称;maxPostSize是用来限制用户上传文件大小的,若超过maxPostSzie,会产生IOException,默认上传文件大小是1MB;encoding可以设定用何种编码方式来上传文件名称,可以解决中文问题。<o:p></o:p>
MultipartRequest类工具有8种方法,利用这些方法,我们可以取得请求的相关信息:<o:p></o:p>
Public Enumeration getParameterNames()<o:p></o:p>
可以取得请求参数的名称<o:p></o:p>
public String getParameter(String name)<o:p></o:p>
此方法传回参数为name的值<o:p></o:p>
public String[] getParameterValues(String name)<o:p></o:p>
此方法主要用在取得当一指定参数具有多个值时,它会传回String的数组<o:p></o:p>
public Enumeration getFileName()<o:p></o:p>
传回所有文件输入类型的名称<o:p></o:p>
public String getFilesystemNames(String name)<o:p></o:p>
用此方法得到上传文件的真正的文件名,这里的name指文件输入类型的名称<o:p></o:p>
public String getContentType(String name)<o:p></o:p>
此方法得到上传文件的内容类型<o:p></o:p>
public File getFile(String name)<o:p></o:p>
此方法得到一个文件对象,代表储存在服务器上的name文件<o:p></o:p>
public String getOriginalFileName(String name)<o:p></o:p>
返回文件在修改政策有效之前的文件名<o:p></o:p>
3 jspsmartUpload
Jspsmartupload组件是由jspsmart公司开发的,安装好它的组件以后,就可以处理文件上传及下载的问题。该组件简单好用,免费,但是源码不公开。<o:p></o:p>
Jspsmartupload Overview:<o:p></o:p>
Free 免费的<o:p></o:p>
upload 1or more files to the server 可上传1个或多个文件<o:p></o:p>
upload to a database 上传文件到数据库<o:p></o:p>
control the upload file by file 可以一列一列的(一个个)控制上传<o:p></o:p>
manage mixed forms files +form fields 可以管理表格文件和表格域<o:p></o:p>
download a file 可以实现文件下载<o:p></o:p>
download a database field 可以从数据库中下载<o:p></o:p>
restrict file size , extension etc 可以限制上传文件的尺寸和类型<o:p></o:p>
MacBinary support MckBinary的支持<o:p></o:p>
Platform: Apache, NT, Unix, Linux, IIS 可以在多种平台上运行<o:p></o:p>
Database : MySQL , Oracle…… 支持多种数据库(最支持MySQL)<o:p></o:p>
整个jspsmartupload压缩包113K,包括有范例、API说明和编译好的class文件,调用这些class文件就可以实习文件的上传下载功能。<o:p></o:p>
<v:shape id="_x0000_i1026" style="width: 414.75pt; height: 299.25pt;" type="#_x0000_t75"><v:imagedata o:title="jspsmartupload" src="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.jpg"></v:imagedata></v:shape>
图2 jspsmartUpoad
Jspsmartupload能实现比O`Rrilly-Cos更多的方法,比如有:<o:p></o:p>
1.public int getSize()方法得到上传文件大小的总和<o:p></o:p>
2.public void setDeniedFilesList(String deniedFilesList)方法设定用户不可上传的类型<o:p></o:p>
3.public void setAllowedFilesList(String allowedFilesList)方法设定用户可上传的文件类型<o:p></o:p>
4.public void setTotalMaxFileSize(Long totalMaxFilesList)设定一次上传文件大小总和 <o:p></o:p>
5.public int getCount()得到Files中的文件个数<o:p></o:p>
6.public Boolean isMissing()测试文件是否确实已经存在<o:p></o:p>
7.public String getFieldName()得到此File在前一个HTML文件中的表格名称<o:p></o:p>
8.public String getFilePathName()得到此File在上传端的文件位置<o:p></o:p>
9.public String getFileExt()得到文件的扩展名<o:p></o:p>
………….<o:p></o:p>
Jspsmartupload的安装:只需把这些class文件拷贝到classes文件夹中即可。<o:p></o:p>
4 <st1:city w:st="on"><st1:place w:st="on">Jakarta</st1:place></st1:city> Apache Struts upload
由于本项目是用Struts结构开发的,所以利用Struts自带的类工具实现上传,这能和工程整体结合的很好,不需要导入其他的包,并且功能强大,使用简单,性能稳定且开源,所以无疑是最佳的选择。<o:p></o:p>
下图是Struts中upload包的结构。基本上要实现上传功能,只要用到FormFiles和MultipartRequestHandler接口就可以解决了。<o:p></o:p>
<v:shape id="_x0000_i1027" style="width: 195pt; height: 258pt;" type="#_x0000_t75"><v:imagedata o:title="struts-upload" src="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_image005.jpg"></v:imagedata></v:shape>
图3 Struts-upload包的结构
基本处理流程是,从页面中传递文件到Form中,然后从Action得到Form中的文件,形成InputStream,然后通过OutputStream写入磁盘。<o:p></o:p>
同样,Struts的upload工具类也可以实现对上传文件大小和类型的控制,可以同时上传多个文件等等。<o:p></o:p>
5 几种方法的比较
<o:p> </o:p> | O`Rrilly-Cos<o:p></o:p> | jspsmartUpload<o:p></o:p> | Struts-upload<o:p></o:p> |
是否开源<o:p></o:p> | 是 | 否 | 是 |
是否免费<o:p></o:p> | 是 | 是 | 是 |
是否继续开发<o:p></o:p> | 是 | 否 | 不明 |
功能<o:p></o:p> | 一般 | 多 | 多 |
可靠性<o:p></o:p> | 高 | 一般 | 高 |
<o:p> </o:p> <o:p> </o:p> <o:p> </o:p> <o:p> </o:p> 特点综述<o:p></o:p> | 免费,开源,不定期增加新功能,可靠性高,代码直接写在jsp文件中 | 简单好用,可上传、下载,功能强大,免费,但是源码不公开,代码直接写在jsp文件中。上传时,文件先预读入内存,当接到save指令时才保存到磁盘,所以上传的性能和文件及内存的大小关系密切。 | 在Struts中使用极为方便,免费,开源,可靠性高,表示层和业务层分离,有后台的Form和Action |
表1 几种上传方法的比较
在研究比较这几种上传组件之后,我认为不管用其中的哪一种都能满足我们的要求,毕竟我们要实现的仅仅是文件上传的功能。最基本的,只要能将文件取得File格式的,就能实现各种各样的功能。<o:p></o:p>
结论是,就本项目而言,使用 Struts-upload 组件是最贴切的选择;如果要做封装的话,最好选择 jspsmartUpload 和 O`Rrilly-Cos 。