`
peng_jian_ming
  • 浏览: 260167 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Commons-fileupload工具的API与开发实例解析(一)

    博客分类:
  • Java
阅读更多
文件上传组件的应用与编写  
在许多Web站点应用中都需要为用户提供通过浏览器上传文档资料的功能,例如,上传邮件附件、个人相片、共享资料等。对文件上传功能,在

浏览器端提供了较好的支持,只要将FORM表单的enctype属性设置为“multipart/form-data”即可;但在Web服务器端如何获取浏览器上传的文

件,需要进行复杂的编程处理。为了简化和帮助Web开发人员接收浏览器上传的文件,一些公司和组织专门开发了文件上传组件。本章将详细介

绍如何使用Apache文件上传组件,以及分析该组件源程序的设计思路和实现方法。
1.1 准备实验环境
按下面的步骤为本章的例子程序建立运行环境:
(1)在Tomcat 5.5.12的<tomcat的安装目录>\webapps目录中创建一个名为fileupload的子目录,并在fileupload目录中创建一个名为test.html

的网页文件,在该文件中写上“这是test.html页面的原始内容!”这几个字符。
(2)在<tomcat的安装目录>\webapps\fileupload目录中创建一个名为WEB-INF的子目录,在WEB-INF目录中创建一个名为classes的子目录和一个

web.xml文件,web.xml文件内容如下:
    <web-app>
    </web-app>
(3)要使用Apache文件上传组件,首先需要安装Apache文件上传组件包。在<tomcat的安装目录>\webapps\fileupload\WEB-INF目录中创建一个

名为lib的子目录,然后从网址http://jakarta.apache.org/commons/fileupload下载到Apache组件的二进制发行包,在本书的附带带光盘中也

提供了该组件的二进制发行包,文件名为commons-fileupload-1.0.zip。从commons-fileupload-1.0.zip压缩包中解压出commons-fileupload

-1.0.jar文件,将它放置进<tomcat的安装目录>\webapps\fileupload\WEB-INF\lib目录中,就完成了Apache文件上传组件的安装。
(4)在<tomcat的安装目录>\webapps\fileupload目录中创建一个名为src的子目录,src目录用于放置本章编写的Java源程序。为了便于对

Servlet源文件进行编译,在src目录中编写一个compile.bat批处理文件,如例程1-1所示。
例程1-1 compile.bat



set PATH=C:\jdk1.5.0_01\bin;%path%
set CLASSPATH=C:\tomcat-5.5.12\common\lib\servlet-api.jar;C:\tomcat-5.5.12\\webapps\
fileupload\WEB-INF\lib\commons-fileupload-1.0.jar;%CLASSPATH%      
javac -d ..\WEB-INF\classes %1
pause



在compile.bat批处理文件中要注意将commons-fileupload-1.0.jar文件的路径加入到CLASSPATH环境变量中和确保编译后生成的class文件存放

到<tomcat安装目录>\webapps\fileupload\WEB-INF\classes目录中,上面的CLASSPATH环境变量的设置值由于排版原因进行了换行,实际上不

应该有换行。接着在src目录中为compile.bat文件创建一个快捷方式,以后只要在Windows资源管理器窗口中将Java源文件拖动到compile.bat

文件的快捷方式上,就可以完成Java源程序的编译了。之所以要创建compile.bat文件的快捷方式,是因为直接将Java源程序拖动到

compile.bat批处理文件时,compile.bat批处理文件内编写的相对路径不被支持。创建完的fileupload目录中的文件结构如图1.1所示。
图1.1
(4)启动Tomcat,在本地计算机的浏览器地址栏中输入如下地址:
    http://localhost:8080/fileupload/test.html
验证浏览器能够成功到该网页文档。如果浏览器无法访问到该网页文档,请检查前面的操作步骤和改正问题,直到浏览器能够成功到该网页文

档为止。
(5)为了让/fileupload这个WEB应用程序能自动重新装载发生了修改的Servlet程序,需要修改Tomcat的server.xml文件,在该文件的<Host>元

素中增加如下一个<Context>子元素:
    <Context path="/fileupload" docBase="fileupload" reloadable="true"/>
保存server.xml文件后,重新启动Tomcat。

1.2 Apache文件上传组件的应用
Java Web开发人员可以使用Apache文件上传组件来接收浏览器上传的文件,该组件由多个类共同组成,但是,对于使用该组件来编写文件上传

功能的Java Web开发人员来说,只需要了解和使用其中的三个类:DiskFileUpload、FileItem和FileUploadException。这三个类全部位于

org.apache.commons.fileupload包中。
1.2.1查看API文档
在准备实验环境时获得的commons-fileupload-1.0.zip文件的解压缩目录中可以看到一个docs的子目录,其中包含了Apache文件上传组件中的

各个API类的帮助文档,从这个文档中可以了解到各个API类的使用帮助信息。打开文件上传组件API帮助文档中的index.html页面,在左侧分栏

窗口页面中列出了文件上传组件中的各个API类的名称,在右侧分栏窗口页面的底部列出了一段示例代码,如图1.2所示。
图1.2
读者不需要逐个去阅读图1.2中列出的各个API类的帮助文档,而应该以图1.2中的示例代码为线索,以其中所使用到的类为入口点,按图索骥地

进行阅读,对于示例代码中调用到的各个API类的方法则应重点掌握。
1.2.2 DiskFileUpload类
DiskFileUpload类是Apache文件上传组件的核心类,应用程序开发人员通过这个类来与Apache文件上传组件进行交互。下面介绍

DiskFileUpload类中的几个常用的重要方法。
1.setSizeMax方法
setSizeMax方法用于设置请求消息实体内容的最大允许大小,以防止客户端故意通过上传特大的文件来塞满服务器端的存储空间,单位为字节

。其完整语法定义如下:
    public void setSizeMax(long sizeMax)
如果请求消息中的实体内容的大小超过了setSizeMax方法的设置值,该方法将会抛出FileUploadException异常。
2.setSizeThreshold方法
Apache文件上传组件在解析和处理上传数据中的每个字段内容时,需要临时保存解析出的数据。因为Java虚拟机默认可以使用的内存空间是有

限的(笔者测试不大于100M),超出限制时将会发生“java.lang.OutOfMemoryError”错误,如果上传的文件很大,例如上传800M的文件,在

内存中将无法保存该文件内容,Apache文件上传组件将用临时文件来保存这些数据;但如果上传的文件很小,例如上传600个字节的文件,显然

将其直接保存在内存中更加有效。setSizeThreshold方法用于设置是否使用临时文件保存解析出的数据的那个临界值,该方法传入的参数的单

位是字节。其完整语法定义如下:
public void setSizeThreshold(int sizeThreshold)
3. setRepositoryPath方法
setRepositoryPath方法用于设置setSizeThreshold方法中提到的临时文件的存放目录,这里要求使用绝对路径。其完整语法定义如下:
public void setRepositoryPath(String repositoryPath)
如果不设置存放路径,那么临时文件将被储存在"java.io.tmpdir"这个JVM环境属性所指定的目录中,tomcat 5.5.9将这个属性设置为了

“<tomcat安装目录>/temp/”目录。
4. parseRequest方法
parseRequest 方法是DiskFileUpload类的重要方法,它是对HTTP请求消息进行解析的入口方法,如果请求消息中的实体内容的类型不是

“multipart/form-data”,该方法将抛出FileUploadException异常。parseRequest 方法解析出FORM表单中的每个字段的数据,并将它们分别

包装成独立的FileItem对象,然后将这些FileItem对象加入进一个List类型的集合对象中返回。parseRequest 方法的完整语法定义如下:
public List parseRequest(HttpServletRequest req)
parseRequest 方法还有一个重载方法,该方法集中处理上述所有方法的功能,其完整语法定义如下:
parseRequest(HttpServletRequest req,int sizeThreshold,long sizeMax,
            String path)
这两个parseRequest方法都会抛出FileUploadException异常。
5. isMultipartContent方法
isMultipartContent方法方法用于判断请求消息中的内容是否是“multipart/form-data”类型,是则返回true,否则返回false。

isMultipartContent方法是一个静态方法,不用创建DiskFileUpload类的实例对象即可被调用,其完整语法定义如下:
public static final boolean isMultipartContent(HttpServletRequest req)
6. setHeaderEncoding方法
由于浏览器在提交FORM表单时,会将普通表单中填写的文本内容传递给服务器,对于文件上传字段,除了传递原始的文件内容外,还要传递其

文件路径名等信息,如后面的图1.3所示。不管FORM表单采用的是“application/x-www-form-urlencoded”编码,还是“multipart/form-data

”编码,它们仅仅是将各个FORM表单字段元素内容组织到一起的一种格式,而这些内容又是由某种字符集编码来表示的。关于浏览器采用何种

字符集来编码FORM表单字段中的内容,请参看笔者编著的《深入体验java Web开发内幕——核心基础》一书中的第6.9.2的讲解,

“multipart/form-data”类型的表单为表单字段内容选择字符集编码的原理和方式与“application/x-www-form-urlencoded”类型的表单是

相同的。FORM表单中填写的文本内容和文件上传字段中的文件路径名在内存中就是它们的某种字符集编码的字节数组形式,Apache文件上传组

件在读取这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回。
对于浏览器上传给WEB服务器的各个表单字段的描述头内容,Apache文件上传组件都需要将它们转换成字符串形式返回,setHeaderEncoding 方

法用于设置转换时所使用的字符集编码,其原理与笔者编著的《深入体验java Web开发内幕——核心基础》一书中的第6.9.4节讲解的

ServletRequest.setCharacterEncoding方法相同。setHeaderEncoding 方法的完整语法定义如下:
public void setHeaderEncoding(String encoding)
其中,encoding参数用于指定将各个表单字段的描述头内容转换成字符串时所使用的字符集编码。
注意:如果读者在使用Apache文件上传组件时遇到了中文字符的乱码问题,一般都是没有正确调用setHeaderEncoding方法的原因。
1.2.3 FileItem类
FileItem类用来封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem对象,通过调用FileItem对象的方法可以获得相关表单字

段元素的数据。FileItem是一个接口,在应用程序中使用的实际上是该接口一个实现类,该实现类的名称并不重要,程序可以采用FileItem接

口类型来对它进行引用和访问,为了便于讲解,这里将FileItem实现类称之为FileItem类。FileItem类还实现了Serializable接口,以支持序

列化操作。
对于“multipart/form-data”类型的FORM表单,浏览器上传的实体内容中的每个表单字段元素的数据之间用字段分隔界线进行分割,两个分隔

界线间的内容称为一个分区,每个分区中的内容可以被看作两部分,一部分是对表单字段元素进行描述的描述头,另外一部是表单字段元素的

主体内容,如图1.3所示。
图 1.3
主体部分有两种可能性,要么是用户填写的表单内容,要么是文件内容。FileItem类对象实际上就是对图1.3中的一个分区的数据进行封装的对

象,它内部用了两个成员变量来分别存储描述头和主体内容,其中保存主体内容的变量是一个输出流类型的对象。当主体内容的大小小于

DiskFileUpload.setSizeThreshold方法设置的临界值大小时,这个流对象关联到一片内存,主体内容将会被保存在内存中。当主体内容的数据

超过DiskFileUpload.setSizeThreshold方法设置的临界值大小时,这个流对象关联到硬盘上的一个临时文件,主体内容将被保存到该临时文件

中。临时文件的存储目录由DiskFileUpload.setRepositoryPath方法设置,临时文件名的格式为“upload_00000005(八位或八位以上的数字)

.tmp”这种形式,FileItem类内部提供了维护临时文件名中的数值不重复的机制,以保证了临时文件名的唯一性。当应用程序将主体内容保存

到一个指定的文件中时,或者在FileItem对象被垃圾回收器回收时,或者Java虚拟机结束时,Apache文件上传组件都会尝试删除临时文件,以

尽量保证临时文件能被及时清除。
下面介绍FileItem类中的几个常用的方法:
1. isFormField方法
isFormField方法用于判断FileItem类对象封装的数据是否属于一个普通表单字段,还是属于一个文件表单字段,如果是普通表单字段则返回

true,否则返回false。该方法的完整语法定义如下:
public boolean isFormField()
2. getName方法
getName方法用于获得文件上传字段中的文件名,对于图1.3中的第三个分区所示的描述头,getName方法返回的结果为字符串“C:\bg.gif”。

如果FileItem类对象对应的是普通表单字段,getName方法将返回null。即使用户没有通过网页表单中的文件字段传递任何文件,但只要设置了

文件表单字段的name属性,浏览器也会将文件字段的信息传递给服务器,只是文件名和文件内容部分都为空,但这个表单字段仍然对应一个

FileItem对象,此时,getName方法返回结果为空字符串"",读者在调用Apache文件上传组件时要注意考虑这个情况。getName方法的完整语法

定义如下:
public String getName()
注意:如果用户使用Windows系统上传文件,浏览器将传递该文件的完整路径,如果用户使用Linux或者Unix系统上传文件,浏览器将只传递该

文件的名称部分。
3.getFieldName方法
getFieldName方法用于返回表单字段元素的name属性值,也就是返回图1.3中的各个描述头部分中的name属性值,例如“name=p1”中的“p1”

。getFieldName方法的完整语法定义如下:
public String getFieldName()
4. write方法
write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法

顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文

件系统中。其完整语法定义如下:
public void write(File file)
5.getString方法
    getString方法用于将FileItem对象中保存的主体内容作为一个字符串返回,它有两个重载的定义形式:
public java.lang.String getString()
public java.lang.String getString(java.lang.String encoding)
    throws java.io.UnsupportedEncodingException
前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元

素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。
6. getContentType方法
getContentType 方法用于获得上传文件的类型,对于图1.3中的第三个分区所示的描述头,getContentType方法返回的结果为字符串

“image/gif”,即“Content-Type”字段的值部分。如果FileItem类对象对应的是普通表单字段,该方法将返回null。getContentType 方法

的完整语法定义如下:
public String getContentType()
7. isInMemory方法
isInMemory方法用来判断FileItem类对象封装的主体内容是存储在内存中,还是存储在临时文件中,如果存储在内存中则返回true,否则返回

false。其完整语法定义如下:
public boolean isInMemory()
8. delete方法
delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete方法将删除该临时文件。尽管Apache组件

使用了多种方式来尽量及时清理临时文件,但系统出现异常时,仍有可能造成有的临时文件被永久保存在了硬盘中。在有些情况下,可以调用

这个方法来及时删除临时文件。其完整语法定义如下:
public void delete()
1.2.4 FileUploadException类
在文件上传过程中,可能发生各种各样的异常,例如网络中断、数据丢失等等。为了对不同异常进行合适的处理,Apache文件上传组件还开发

了四个异常类,其中FileUploadException是其他异常类的父类,其他几个类只是被间接调用的底层类,对于Apache组件调用人员来说,只需对

FileUploadException异常类进行捕获和处理即可。
分享到:
评论

相关推荐

    commons-fileupload-1.3.3.jar commons-io-2.5.jar

    Apache Commons IO则是Apache Commons项目中的另一个关键组件,它提供了大量与I/O(输入/输出)相关的实用工具类。`commons-io-2.5.jar` 包含了各种I/O操作的通用功能,如文件读写、流操作、文件比较、文件过滤等。...

    commons-fileupload.rar;包括commons-fileupload-1.3.1-bin和commons-io-2.4

    而`commons-io-2.4`是Apache Commons IO库的2.4版本,它是处理输入/输出操作的工具集,与FileUpload配合处理文件上传时,常被用到。 文件上传在Web应用中的实现并不直接内置在Servlet API中,因此,`commons-...

    commons-fileupload-1.3.2.jar

    总之,Apache Commons FileUpload是Java Web开发中处理文件上传不可或缺的工具,它提供了高效、灵活且安全的文件上传解决方案。通过理解和熟练运用这个库,开发者可以轻松地在自己的应用中实现复杂的文件上传功能。

    commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar

    Apache Commons FileUpload与Apache Commons IO是Java开发中处理文件上传的两个重要库。它们为开发者提供了强大而灵活的工具,使得在Web应用中处理文件上传变得简单易行。 `commons-fileupload-1.2.1.jar`是Apache ...

    commons-fileupload-1.2.2.jar和commons-io-2.4.jar包

    总之,`commons-fileupload-1.2.2.jar`和`commons-io-2.4.jar`是Java Web开发中处理文件上传和下载不可或缺的工具。尽管它们的版本可能不是最新的,但依然能提供可靠的功能,并且在很多现有的系统中广泛使用。理解并...

    maven实现的commons-fileupload的demo

    在Java Web开发中,文件上传是一项常见的功能,Apache Commons FileUpload库是实现这一功能的强大工具。本示例将深入解析如何结合Maven构建一个基于Servlet的文件上传演示项目。Maven是一个项目管理工具,它可以帮助...

    java文件上传jar(commons-fileupload-1.2.1.jar,commons-io-2.0.1.jar)

    在"commons-fileupload-1.2.1.jar"这个版本中,它提供了一个简洁的API,使得开发者可以轻松地解析请求并获取上传的文件。 具体来说,FileUpload库允许你创建一个`DiskFileItemFactory`实例来配置临时存储参数,然后...

    commons-fileupload 文件上传 图片上传 demo

    `commons-file`标签可能是指与`commons-fileupload`相关的所有操作,包括文件读写、文件处理等。而`图片上传`则特指使用该库上传图片文件的场景。 至于文件列表中提到的"Roger",这可能是实际的项目文件或代码示例...

    java 上传 SmartUpload&commons-fileupload

    使用Commons-Fileupload,你需要配置Servlet容器来解析多部分请求,并创建`DiskFileItemFactory`来处理临时文件存储,接着创建`FileUpload`实例进行文件解析。 在选择使用哪个组件时,应考虑项目需求和团队的熟悉...

    commons-fileupload-1.2.1

    使用这个组件时,开发者需要在他们的项目中引入`commons-fileupload-1.2.1.jar`,并创建一个`DiskFileItemFactory`实例来配置临时存储位置和内存阈值。然后,他们可以通过`ServletFileUpload`类解析请求,获取`...

    commons-fileupload-1.3.2.jar和commons-io-2.5.jar

    "commons-fileupload-1.3.2.jar" 提供了处理这种类型请求的API,它能够解析请求体,将文件和文本字段分开,然后将文件数据存储到临时文件或内存中。这个库支持大文件上传,可以设置内存阈值,超过该阈值时,文件会被...

    commons-fileupload相关架包

    总的来说,Apache Commons FileUpload和Commons IO是Java Web开发中处理文件上传不可或缺的工具,它们简化了这个过程,提高了代码的可读性和可维护性。通过合理配置和使用这两个库,开发者可以构建安全、高效、用户...

    commons-fileupload.jar和commons-io-1.4.jar

    总的来说,`commons-fileupload.jar`和`commons-io-1.4.jar`是Java Web开发中实现文件上传功能必不可少的工具,它们为开发者提供了强大且灵活的接口,简化了文件上传的实现过程。了解并熟练掌握这两个库的使用,有助...

    commons-fileupload-1.2.1.jar

    6. **API使用**:使用FileUpload库通常涉及创建一个`ServletFileUpload`实例,然后使用`parseRequest()`方法解析请求,得到`FileItem`对象。每个`FileItem`代表表单的一个字段或上传的文件,可以从中获取名称、内容...

    commons-fileupload

    `commons-io-1.3.2.jar`是Apache Commons IO库,它是`commons-fileupload`依赖的库,提供了各种与I/O操作相关的工具类。例如,`FileUtils`类提供了文件和目录的便捷操作,如复制、移动、删除等。在处理文件上传时,...

    commons-fileupload + commons-io-1.4.jar

    Apache Commons FileUpload与Apache Commons IO是Java开发中用于处理文件上传功能的重要库。这两个库的组合在处理HTTP请求中的文件上传部分尤其有用,特别是在Web应用中。下面将详细阐述这两个库的功能、使用方法...

    commons-fileupload文件上传实例代码

    在Java Web开发中,文件上传是一项常见的功能,Apache Commons FileUpload库为开发者提供了方便、灵活的文件上传解决方案。本教程将深入讲解如何使用`commons-fileupload`库处理中文乱码问题以及实现多文件上传。 ...

    commons-fileupload-1.2.2.zip

    Apache Commons FileUpload是Java中处理HTTP请求中文件上传的一个强大工具,尤其在Web开发中扮演着重要角色。这个组件是Apache软件基金会的Commons项目的一部分,旨在简化从HTTP请求中提取上传文件的任务。在本文中...

    java上传下载需要的jar:commons-fileupload-1.2.jar+commons-io-1.3.2.jar

    `commons-io-1.3.2.jar` 是Apache Commons IO库的一个较旧版本,它提供了大量实用的IO操作工具类。这个库广泛用于Java项目中,因为它包含了许多方便的功能,如文件复制、移动、删除,读写流,转换字符集,以及各种...

Global site tag (gtag.js) - Google Analytics