`
fanta123
  • 浏览: 7049 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Apache FileUpload文件上传组件API解析

阅读更多
Java Web开发人员可以使用Apache文件上传组件来接收浏览器上传的文件,该组件由多个类共同组成,但是,对于使用该组件来编写文件上传功能的Java Web开发人员来说,只需要了解和使用其中的三个类:DiskFileUpload、FileItem和FileUploadException。这三个类全部位于org.apache.commons.fileupload包中。

  1. DiskFileUpload类

  DiskFileUpload类是Apache文件上传组件的核心类,应用程序开发人员通过这个类来与Apache文件上传组件进行交互。但现在Apache建议使用ServletFileUpload类,两个类的方法类似。下面介绍DiskFileUpload类中的几个常用的重要方法。

  1.1.setSizeMax方法

  setSizeMax方法用于设置请求消息实体内容的最大允许大小,以防止客户端故意通过上传特大的文件来塞满服务器端的存储空间,单位为字节。其完整语法定义如下:

  public void setSizeMax(long sizeMax)

  如果请求消息中的实体内容的大小超过了setSizeMax方法的设置值,该方法将会抛出FileUploadException异常。

  1.2.setSizeThreshold方法

  Apache文件上传组件在解析和处理上传数据中的每个字段内容时,需要临时保存解析出的数据。因为Java虚拟机默认可以使用的内存空间是有限的(笔者测试不大于100M),超出限制时将会发生“java.lang.OutOfMemoryError”错误,如果上传的文件很大,例如上传800M的文件,在内存中将无法保存该文件内容,Apache文件上传组件将用临时文件来保存这些数据;但如果上传的文件很小,例如上传600个字节的文件,显然将其直接保存在内存中更加有效。setSizeThreshold方法用于设置是否使用临时文件保存解析出的数据的那个临界值,该方法传入的参数的单位是字节。其完整语法定义如下:

  public void setSizeThreshold(int sizeThreshold)

  1.3. setRepositoryPath方法

  setRepositoryPath方法用于设置setSizeThreshold方法中提到的临时文件的存放目录,这里要求使用绝对路径。其完整语法定义如下:

  public void setRepositoryPath(String repositoryPath)

  如果不设置存放路径,那么临时文件将被储存在"java.io.tmpdir"这个JVM环境属性所指定的目录中,tomcat 5.5.9将这个属性设置为了“<tomcat安装目录>/temp/”目录。

  1.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异常。

  1.5. isMultipartContent方法

  isMultipartContent方法方法用于判断请求消息中的内容是否是“multipart/form-data”类型,是则返回true,否则返回false。isMultipartContent方法是一个静态方法,不用创建DiskFileUpload类的实例对象即可被调用,其完整语法定义如下:

  public static final boolean isMultipartContent(HttpServletRequest req)

  1.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方法的原因。

  2.  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类中的几个常用的方法:

  2.1. isFormField方法

  isFormField方法用于判断FileItem类对象封装的数据是否属于一个普通表单字段,还是属于一个文件表单字段,如果是普通表单字段则返回true,否则返回false。该方法的完整语法定义如下:

  public boolean isFormField()

  2.2. getName方法

  getName方法用于获得文件上传字段中的文件名,对于图1.3中的第三个分区所示的描述头,getName方法返回的结果为字符串“C:\bg.gif”。如果FileItem类对象对应的是普通表单字段,getName方法将返回null。即使用户没有通过网页表单中的文件字段传递任何文件,但只要设置了文件表单字段的name属性,浏览器也会将文件字段的信息传递给服务器,只是文件名和文件内容部分都为空,但这个表单字段仍然对应一个FileItem对象,此时,getName方法返回结果为空字符串"",读者在调用Apache文件上传组件时要注意考虑这个情况。getName方法的完整语法定义如下:

  public String getName()

  注意:如果用户使用Windows系统上传文件,浏览器将传递该文件的完整路径,如果用户使用Linux或者Unix系统上传文件,浏览器将只传递该文件的名称部分。

  2.3.getFieldName方法

  getFieldName方法用于返回表单字段元素的name属性值,也就是返回图1.3中的各个描述头部分中的name属性值,例如“name=p1”中的“p1”。getFieldName方法的完整语法定义如下:

  public String getFieldName()

  2.4. write方法

  write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。其完整语法定义如下:

  public void write(File file)

  2.5.getString方法

  getString方法用于将FileItem对象中保存的主体内容作为一个字符串返回,它有两个重载的定义形式:

  public java.lang.String getString()

  public java.lang.String getString(java.lang.String encoding)

  throws java.io.UnsupportedEncodingException

  前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。

  2.6. getContentType方法

  getContentType 方法用于获得上传文件的类型,对于图1.3中的第三个分区所示的描述头,getContentType方法返回的结果为字符串“image/gif”,即“Content-Type”字段的值部分。如果FileItem类对象对应的是普通表单字段,该方法将返回null。getContentType 方法的完整语法定义如下:

  public String getContentType()

  2.7. isInMemory方法

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

  public boolean isInMemory()

  2.8. delete方法

  delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete方法将删除该临时文件。尽管Apache组件使用了多种方式来尽量及时清理临时文件,但系统出现异常时,仍有可能造成有的临时文件被永久保存在了硬盘中。在有些情况下,可以调用这个方法来及时删除临时文件。其完整语法定义如下:

  public void delete()

  3. FileUploadException类

  在文件上传过程中,可能发生各种各样的异常,例如网络中断、数据丢失等等。为了对不同异常进行合适的处理,Apache文件上传组件还开发了四个异常类,其中FileUploadException是其他异常类的父类,其他几个类只是被间接调用的底层类,对于Apache组件调用人员来说,只需对FileUploadException异常类进行捕获和处理即可。

  4. ServletRequestContext

  ServletRequestContext类提供访问request的方法。实现RequestContext接口。[size=medium]
[/size]

示例代码:
package web;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class FileUpLoadServlet extends HttpServlet {

public void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
DiskFileItemFactory dfif = new DiskFileItemFactory();
//dfif.setSizeThreshold(10000);
//解析时,需要使用以上配置
ServletFileUpload sfu = new ServletFileUpload(dfif);
try {
//开始解析,解析的结果是一个FileItem的集合。
//每一个FileItem,代表表单中的一个域。
   List items = sfu.parseRequest(request);
   for(int i=0;i<items.size();i++){
FileItem item = (FileItem) items.get(i);
//isFormField():表示表单域不是文件上传。比如input type="text"
if(item.isFormField()){
   String fieldName = item.getFieldName();
   String value = item.getString();
   System.out.println(fieldName+":"+value);
}else{
String filename1 = item.getName();
String filename = filename1.substring(filename1.indexOf("\\")+1);
//选择一个存放文件的目录,该目录应该是服务器上的某个目录
//getRealPath("upload"):获得服务器上的某个目录的绝对路径
String path = this.getServletContext().getRealPath("upload");
System.out.println("path:"+path);
item.write(new File(path+"/"+filename));
}
}
} catch (Exception e) {
e.printStackTrace();
throw new ServletException(e.getMessage());
}
}

}
分享到:
评论

相关推荐

    commons-fileupload文件上传组件中文教程--张孝祥写的

    - 创建`lib`目录,并下载Apache Commons FileUpload组件(版本1.0),解压后将`commons-fileupload-1.0.jar`放入`lib`目录。 - 创建`src`目录用于存放Java源代码,并编写`compile.bat`批处理文件以便于编译Java...

    16上传下载JSP源码实例+教程.rar

    `Apache FileUpload文件上传组件API解析.doc`文档应该详细介绍了该组件的使用方法和API,包括如何创建解析器、如何配置最大上传大小、如何处理文件等。 2. **上传实现原理**:`上传实现原理.doc`文档可能深入探讨了...

    java文件上传组件包(fileupload)

    FileUpload组件基于Servlet API,通过解析请求体中的多部分数据来提取上传的文件。多部分数据是HTTP协议中用于上传文件的一种格式,通常在HTML表单中通过`enctype="multipart/form-data"`属性启用。该组件支持分块...

    commons-fileupload文件上传实例代码

    - 上传文件时,应检查文件类型和大小,防止恶意文件上传。 - 文件名处理时,避免使用用户提供的原始文件名,以防路径遍历攻击。可以生成随机文件名或重命名文件。 - 使用临时目录存储上传的文件,直到准备好处理...

    Java 文件上传组件 Apache Commons FileUpload 应用指南

    - RFC1867 引入了在 HTML 表单中上传文件的功能,要求使用 `multipart/form-data` 编码类型。客户端浏览器在提交包含文件的表单时,会将文件内容分割并编码,然后以多部分消息体的形式发送给服务器。 - 服务器端...

    利用Common-fileupload封装的文件上传组件...附上源码.

    `Common-fileupload`是Apache组织提供的一个Java库,用于处理HTTP协议中的多部分文件上传请求。这个组件封装了复杂的过程,使得开发者能够轻松地在服务器端接收并处理上传的文件。 首先,我们来看一下标题:“利用...

    fileupload组件上传文档介绍

    Apache Commons FileUpload 是一款广泛使用的文件上传组件,它简化了文件上传的处理流程,使开发者能够轻松地处理客户端发送过来的文件。本节将详细介绍如何准备实验环境以便使用此组件。 #### 三、实验环境准备 ...

    使用commons-fileupload上传文件

    【使用commons-fileupload上传文件】 Apache Commons FileUpload是Apache组织的一个子项目,专注于处理HTTP文件上传。这个组件提供了一个简洁的API,使得开发者能够轻松地在Java应用中处理由浏览器发送的多部分...

    文件上传组件-Apache-Commons-FileUpload-应用指南.docx

    以下是对Apache Commons FileUpload组件的应用指南: 1. **获取上传组件**: - 首先,你需要访问Apache Commons FileUpload的官方网站(http://commons.apache.org/proper/commons-fileupload/)下载最新版本的...

    fileupload文件上传与配置

    `Commons BeanUtils`(`commons-beanutils.jar`)虽然不是Fileupload的主要组成部分,但它是Apache Commons项目中的另一个工具库,用于简化JavaBean对象的属性操作,有时在处理上传文件时,可能会用到它来帮助处理...

    jsp+servlet+fileupload文件上传

    - **文件上传**:这是整个示例的核心功能,涉及到用户通过Web页面上传文件到服务器的过程。 **文件名解析:** "多文件上传--fileupload" 这个文件名表明压缩包内可能包含一个多文件上传的示例,具体使用了...

    WEB 文件上传组件

    Apache Commons FileUpload提供了API,可以帮助开发者解析请求中的多个部分,包括文件内容,从而轻松实现文件上传功能。 1. **Apache Commons FileUpload** - **作用**:解析HTTP多部分请求,将文件内容转换为可...

    java文件上传组件包

    `javax.servlet.http.HttpServletRequest`接口提供了获取上传文件的方法,如`getPart()`或`getParts()`,用于获取请求中的多部分数据。 2. **Multipart解析**:在HTTP协议中,文件上传通常使用`multipart/form-data...

    文件上传组件-Apache-Commons-FileUpload-应用指南.pdf

    服务器端,Apache Commons FileUpload库负责解析这种多部分的数据,将每个部分(包括文本和文件)转换为易于操作的对象。 3. **使用步骤** - 创建一个Servlet或其他处理HTTP请求的类,导入必要的FileUpload库。 -...

    JAVAWeb文件上传组件

    以上就是关于“JAVAWeb文件上传组件”的基本介绍,包括Apache Commons FileUpload和Commons IO的作用以及它们在Struts2框架中的使用。通过理解这些知识点,开发者可以有效地实现在Java Web应用中处理文件上传的需求...

    common fileupload上传组件包

    这个库提供了处理请求、解析请求体中的文件项、存储上传文件到临时或持久位置等功能。它简化了Web开发者处理文件上传的复杂性,使其能够优雅地处理大文件上传、错误处理以及文件大小限制等问题。 **知识点详解** 1...

    fileupload jsp上传下载组件和使用方法

    上传文件" name="submit"&gt; ``` 4. **处理上传请求** 在服务器端,通常是一个Servlet来处理上传请求。以下是一个简单的示例: ```java import org.apache.commons.fileupload.FileItem; import org.apache....

    Apache 文件上传

    Apache Commons FileUpload组件是Java领域处理文件上传的常用工具库,它使得开发者能够轻松地处理HTTP协议中的多部分表单数据。本篇文章将深入探讨Apache FileUpload的工作原理和使用方法。 1. **多部分表单数据** ...

Global site tag (gtag.js) - Google Analytics