上传文件,表单form的enctype="multipart/form-data",是以二进制数据流提交数据的。所以没法用request.getParameter("name")来获取提交到后台的普通表单域值。
下面是具体的利用Apache Commons FileUpload组件来上传文件,并获取普通表单域的数据。
e.g
Servlet代码:
String fileDir = this.getServletContext().getRealPath("temp/");
String localFileName = "";
String serverFileName = "";
String serverFilePath = "";
if(ServletFileUpload.isMultipartContent(request)) {
DiskFileItemFactory factory = new DiskFileItemFactory(); // 基于磁盘文件项目创建一个工厂对象
//factory.setSizeThreshold(20*1024);
factory.setRepository(factory.getRepository());
ServletFileUpload upload = new ServletFileUpload(factory); // 创建一个新的文件上传对象
int size = 10*1024*1024; // 最大上传文件,不超过10M
List formlists = null;
FileItem formitem;
try{
formlists = upload.parseRequest(request); // 解析上传请求
}catch(FileUploadException e){
e.printStackTrace();
}
Iterator iter = formlists.iterator(); // 枚举方法
while(iter.hasNext()) {
formitem = (FileItem)iter.next(); // 获取FileItem对象
if(!formitem.isFormField()) { // 判断是否为文件域
if(formitem.getName()!=null && !formitem.getName().equals("")) { // 判断是否选择了文件
long upFileSize = formitem.getSize(); // 上传文件大小
if (upFileSize > size) {
out.print("<script>alert('上传文件太大![<100M]')</script>");
return;
}
localFileName = formitem.getName(); // 获取文件名
int ii = localFileName.lastIndexOf(".");
String sExt = localFileName.substring(ii,localFileName.length());//取文件名的后缀
if ((!sExt.equals(".xls")) && (!sExt.equals(".xlsx"))) {
out.print("<script>alert('请选择excel文件!')</script>");
return;
}
//得到不重复的文件名,这一步是为了防止同时上传两个同文件名的excel而做的,避免文件名重复
Date dt = new Date(System.currentTimeMillis());
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
serverFileName = fmt.format(dt);
serverFileName = serverFileName + sExt;
//如果不存在该目录,则新建一个
File dir =new File(fileDir);
if (!dir.exists()) {
dir.mkdirs();
}
serverFilePath = fileDir+"\\"+serverFileName;
File serverFile = new File(serverFilePath);
try {
formitem.write(serverFile);
}catch(Exception e) {
e.printStackTrace();
}
}else {
out.print("<script>alert('没有选择文件!')</script>");
return;
}
}else {
try {
if("column".equals(formitem.getFieldName())) {
column = Integer.parseInt(formitem.getString("gb2312").trim());
//System.out.println(column);
}
}catch (NumberFormatException e) {
e.printStackTrace();
return;
}
}
}
HTML代码:
<form enctype="multipart/form-data" id="form1" name="form1" action="UploadServlet" method="post">
<input type="file" id="uploadfile" name="uploadfile" />
<input type="text" name="column" />
<input type="submit" value="上传" name="submit">
</form>
主要功能是,上传excel文件到/temp/目录下,为了测试获取普通表单域的值,放置了一个name为column的text。
--------------------------------------------------------------------------------
FileItem类的常用方法:
1. boolean isFormField()
isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。因此,可以使用该方法判断是否为普通表单域,还是文件上传表单域。
2. String getName()
getName方法用于获得文件上传字段中的文件名。
注意IE或FireFox中获取的文件名是不一样的,IE中是绝对路径,FireFox中只是文件名。
3. String getFieldName()
getFieldName方法用于返回表单标签name属性的值。如上例中<input type="text" name="column" />的value。
4. void write(File file)
write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。
5. String getString()
getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:
public java.lang.String getString()
public java.lang.String getString(java.lang.String encoding)
throws java.io.UnsupportedEncodingException
前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。
6. String getContentType()
getContentType 方法用于获得上传文件的类型,即表单字段元素描述头属性“Content-Type”的值,如“image/jpeg”。如果FileItem类对象对应的是普通表单字段,该方法将返回null。
7. boolean isInMemory()
isInMemory方法用来判断FileItem对象封装的数据内容是存储在内存中,还是存储在临时文件中,如果存储在内存中则返回true,否则返回false。
8. void delete()
delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete方法将删除该临时文件。
尽管当FileItem对象被垃圾收集器收集时会自动清除临时文件,但及时调用delete方法可以更早的清除临时文件,释放系统存储资源。另外,当系统出现异常时,仍有可能造成有的临时文件被永久保存在了硬盘中。
9. InputStream getInputStream()
以流的形式返回上传文件的数据内容。
10. long getSize()
返回该上传文件的大小(以字节为单位)。
DiskFileItemFactory类
将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现) 对象的任务
由 org.apache.commons.fileupload.FileItemFactory 接口的默认实现
org.apache.commons.fileupload.disk.DiskFileItemFactory 来完成。当上传的文件项目比较小时,直接保存在内存中(速度比较快),比较大时,以临时文件的形式,保存在磁盘临时文件夹(虽然速度慢些,但是内存资源是有限的)。
属性
1) public static final int DEFAULT_SIZE_THRESHOLD :将文件保存在内存还是磁盘临时文件夹的默认临界值,值为10240,即10kb。
2) private File repository:用于配置在创建文件项目时,当文件项目大于临界值时使用的临时文件夹,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir获取。如下代码:
System.getProperty("java.io.tmpdir");
3) private int sizeThreshold:用于保存将文件保存在内存还是磁盘临时文件夹的临界值
构造方法
1) public DiskFileItemFactory()
采用默认临界值和系统临时文件夹构造文件项工厂对象。
2) public DiskFileItemFactory(int sizeThreshold,File repository)
采用参数指定临界值和系统临时文件夹构造文件项工厂对象。
3) FileItem createItem()
根据DiskFileItemFactory相关配置将每一个请求消息实体项目创建成DiskFileItem 实例,并返回。该方法从来不需要我们亲自调用,FileUpload组件在解析请求时内部使用。
4) void setSizeThreshold(int sizeThreshold)
Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为Java虚拟机默认可以使用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。
setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的getSizeThreshold() 方法用来获取此临界值。
5) void setRepository(File repository)
setRepositoryPath方法用于设置当上传文件尺寸大于setSizeThreshold方法设置的临界值时,将文件以临时文件形式保存在磁盘上的存放目录。有一个对应的获得临时文件夹的 File getRespository() 方法。
注意:当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir 获取。如下代码:
System.getProperty("java.io.tmpdir");
Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。
ServletFileUpload 类
org.apache.commons.fileupload.servlet.ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类(所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。
使用其parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。使用该方法处理上传文件简单易用。
如果你希望进一步提高新能,你可以采用 getItemIterator 方法,直接获得每一个文件项的数据输入流,对数据做直接处理。
在使用ServletFileUpload对象解析请求时需要根据DiskFileItemFactory对象的属性sizeThreshold(临界值)和repository(临时目录)来决定将解析得到的数据保存在内存还是临时文件中,如果是临时文件,保存在哪个临时目录中?。所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。
ServletFileUpload继承结构:
java.lang.Object
|—org.apache.commons.fileupload.FileUploadBase
|—org.apache.commons.fileupload.FileUpload
|—org.apache.commons.fileupload.servlet.ServletFileUpload
构造方法:
1) public ServletFileUpload()
构造一个未初始化的实例,需要在解析请求之前先调用setFileItemFactory()方法设置 fileItemFactory属性。
2) public ServletFileUpload(FileItemFactory fileItemFactory)
构造一个实例,并根据参数指定的FileItemFactory 对象,设置 fileItemFactory属性。
ServletFileUpload类常用方法:
1) public void setSizeMax(long sizeMax)
setSizeMax方法继承自FileUploadBase类,用于设置请求消息实体内容(即所有上传数据)的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。
在请求解析的过程中,如果请求消息体内容的大小超过了setSizeMax方法的设置值,将会抛出FileUploadBase内部定义的SizeLimitExceededException异常(FileUploadException的子类)。该方法有一个对应的读方法:public long getSizeMax()方法。
2) public void setFileSizeMax(long fileSizeMax)
setFileSizeMax方法继承自FileUploadBase类,用于设置单个上传文件的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。该方法有一个对应的读方法:public long geFileSizeMax()方法。
在请求解析的过程中,如果单个上传文件的大小超过了setFileSizeMax方法的设置值,将会抛出FileUploadBase内部定义的FileSizeLimitExceededException异常(FileUploadException的子类)。
3) public List parseRequest(javax.servlet.http.HttpServletRequest req)
parseRequest 方法是ServletFileUpload类的重要方法,它是对HTTP请求消息体内容进行解析的入口方法。它解析出FORM表单中的每个字段的数据,并将它们分别包装成独立的FileItem对象,然后将这些FileItem对象加入进一个List类型的集合对象中返回。
该方法抛出FileUploadException异常来处理诸如文件尺寸过大、请求消息中的实体内容的类型不是“multipart/form-data”、IO异常、请求消息体长度信息丢失等各种异常。每一种异常都是FileUploadException的一个子类型。
4) public FileItemIterator getItemIterator(HttpServletRequest request)
getItemIterator方法和parseRequest 方法基本相同。但是getItemIterator方法返回的是一个迭代器,该迭代器中保存的不是FileItem对象,而是FileItemStream 对象,如果你希望进一步提高新能,你可以采用getItemIterator方法,直接获得每一个文件项的数据输入流,做底层处理;如果性能不是问题,你希望代码简单,则采用parseRequest方法即可。
5) public stiatc boolean isMultipartContent(HttpServletRequest req)
isMultipartContent方法方法用于判断请求消息中的内容是否是“multipart/form-data”类型,是则返回true,否则返回false。isMultipartContent方法是一个静态方法,不用创建ServletFileUpload类的实例对象即可被调用。
6) getFileItemFactory()和setFileItemFactory(FileItemFactory)
方法继承自FileUpload类,用于设置和读取fileItemFactory属性。
7) public void setProgressListener(ProgressListener pListener)
设置文件上传进度监听器。该方法有一个对应的读取方法:ProgressListener getProgressListener()。
8) public void setHeaderEncoding()
在文件上传请求的消息体中,除了普通表单域的值是文本内容以外,文件上传字段中的文件路径名也是文本,在内存中保存的是它们的某种字符集编码的字节数组,Apache文件上传组件在读取这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回。
setHeaderEncoding方法继承自FileUploadBase类,用于设置上面提到的字符编码。如果没有设置,则对应的读方法getHeaderEncoding()方法返回null,将采用HttpServletRequest设置的字符编码,如果HttpServletRequest的字符编码也为null,则采用系统默认字符编码。可以通过一下语句获得系统默认字符编码:
System.getProperty("file.encoding"));
参考:http://www.blogjava.net/whistler/articles/330976.html
分享到:
相关推荐
Apache Commons ...总的来说,Apache Commons FileUpload为Java开发者提供了强大的文件上传支持,简化了处理多部分表单数据的过程。了解其工作原理和使用方法,可以帮助我们更好地构建安全、高效的文件上传功能。
在HTML表单提交文件时,通常会使用`enctype="multipart/form-data"`属性,此时,数据会被分割成多个部分,每个部分都有自己的头部信息和内容,这就是多部分数据。Commons FileUpload库就是用来解析这样的数据流。 1...
【使用commons-fileupload上传文件】 Apache Commons FileUpload是Apache组织的一个子项目,专注于处理HTTP文件上传。这个组件提供了一个简洁的API,使得开发者能够轻松地在Java应用中处理由浏览器发送的多部分...
开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2...
apache commons.fileupload上传组件在上传文件时,在调用parseRequest方法时,先将输入流上传到服务器临时目录,在之后的文件处理过程中,再将临时目录下保存的文件复制到指定的目录,多了一道转储步骤。本实现抽取...
Apache Commons FileUpload是Java中处理文件上传的一个强大库,它简化了这一过程。本教程将详细介绍如何利用commons-fileupload实现文件上传功能,并提供一个简单的实例。 **一、Apache Commons FileUpload简介** ...
4. **错误处理**:`commons-fileupload`还提供了处理上传过程中可能出现的错误和异常的机制,如文件大小超出限制、文件类型不合法等。 在`描述`中提到的`commons-fileupload-1.2.2.jar`和`commons-io.jar`是实现...
在Java Web开发中,文件上传是一项常见的功能,Apache Commons FileUpload库为开发者提供了方便、灵活的文件上传解决方案。本教程将深入讲解如何使用`commons-fileupload`库处理中文乱码问题以及实现多文件上传。 ...
当用户通过表单提交包含文件的表单时,表单的`method`属性必须设置为`POST`,并且`enctype`属性应设为`multipart/form-data`。这样,浏览器会将表单数据分割成多个部分,每部分前都有一个分隔符,以便服务器可以解析...
这个组件使得在Web应用中接收用户通过表单提交的多个文件变得容易。基于此库,我们可以创建一个简单的文件上传组件,以处理文件上传请求,存储上传的文件,并进行必要的错误检查和异常处理。 以下是一些关于Apache ...
在本文中,我们将深入探讨如何使用Apache Commons FileUpload组件来实现文件上传功能。Apache Commons FileUpload是一个用于处理HTTP请求中的多部分数据的Java库,它使得在Servlet或JSP应用中处理文件上传变得简单易...
### Commons-FileUpload 实现文件上传下载 #### 知识点概述 Commons-FileUpload 是 Apache 提供的一个用于处理 HTTP 文件上传的组件。它基于 Servlet 规范,并且能够解析来自 `multipart/form-data` 编码类型的 ...
在Java EE开发中,文件上传是一项常见的功能,Apache Commons FileUpload库正是为了处理这个需求而设计的。这个库提供了一套强大的API,使得在Servlet环境中处理文件上传变得简单且高效。下面将详细介绍Apache ...
总的来说,Apache Commons FileUpload是Java Web开发中不可或缺的工具,它简化了文件上传的复杂性,使得开发者能够更专注于业务逻辑,而不用过多关心底层的文件处理细节。正确使用和配置这个库,可以在保证用户体验...
Commons FileUpload是Apache组织提供的一款强大的Java文件上传处理组件,常用于Web应用中处理用户通过表单上传的文件。在Web开发中,尤其是在涉及到用户上传照片、文档等大文件时,FileUpload组件提供了方便、高效的...
commons commons-fileupload历史版本jar包集合,包括src源码 附件列表: commons-fileupload-1.0.zip commons-fileupload-1.1.1.zip commons-fileupload-1.1.zip commons-fileupload-1.2.1-bin.zip commons-...
在Java Web开发中,文件上传和下载是常见的功能需求,Apache Commons FileUpload库提供了一种高效、方便的方式来处理这些操作。本教程将详细介绍如何利用commons-fileupload库来实现在Java Web应用中的文件上传和...
赠送Maven依赖信息文件:commons-fileupload-1.4.pom; 包含翻译后的API文档:commons-fileupload-1.4-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-fileupload:commons-fileupload:1.4; 标签:...
当用户通过表单提交文件时,服务器端需要解析这些数据并将其存储到一个临时或指定的位置。FileUpload库提供了`DiskFileItemFactory`和`ServletFileUpload`这两个关键类,前者用于在内存或磁盘上创建文件项,后者则...