文件上传:

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中, 在使用ServletFileUpload对象解析请求时需要根据DiskFileItemFactory对象的属性sizeThreshold(临界值)和repository(临时目录)来决定将解析得到的数据保存在内存还是临时文件中,如果是临时文件,保存在哪个临时目录中?。所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。

FileItem类

在HTML页面input  必须有 name  <input type="file" name="filename">

表单如果包含一个文件上传输入项的话,这个表单的enctype属性就必须设置为multipart/form-data

<form action ="/day16/servlet/UpLoadServlet" enctype="multipart/form-data" method="post">

浏览器表单的类型如果为multipart/form-data,那么浏览器在提交表单数据时,它将采用MIME协议对数据进行封装后提交,在服务器这端也将不能采用

原来传统的方工获取数据了。在服务器端想获取数据就要通过流。request提供了一个getInputStream读取流。

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()
      返回该上传文件的大小(以字节为单位)。

为了方便用户处理文件上传数据,Apache开源组织提供了一个用来处理表单文件上传的一个开源组件(Commons-fileupload).使用Commons-fileupload组件实现文件上传,需要导入该组件相应的jar包.

Commons-fileupload和commons-io两个jar包.

DiskFileItemFactory是创建FileItem对象的工厂包括方法:

1.public void setSizeThreshold(int?sizeThreshold) 
设置内存缓冲区的大小,默认值为10K,如果文件大于10K,将使用临时文件缓

存上传文件.

2.public void setRepository(Java.io.File repository)
指定临时文件目录

3.public DiskFileItemFactory();

ServletFileUpload 类

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中.

org.apache.commons.fileupload.servlet.ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类(所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。

使用其parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。使用该方法处理上传文件简单易用。

如果你希望进一步提高新能,你可以采用 getItemIterator 方法,直接获得每一个文件项的数据输入流,对数据做直接处理。

在使用ServletFileUpload对象解析请求时需要根据DiskFileItemFactory对象的属性sizeThreshold(临界值)和repository(临时目录)来决定将解析得到的数据保存在内存还是临时文件中,如果是临时文件,保存      在哪个临时目录中?。所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的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"));

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/”。

文件上传: FileItem类、ServletFileUpload 类、DiskFileItemFactory类的更多相关文章

  1. PHP文件上传,下载,Sql工具类!

    PHP文件上传,下载,Sql工具类! 对文件大小,文件类型 同名覆盖 中文转码的操作,可直接使用 前台 upload.html <!DOCTYPE html> <html> & ...

  2. tp文件上传;org/RBAC.class.php 权限类;think/page,class,php分页类;

    一.上传表单: 注意,要使用上传功能 你的表单需要设置 enctype="multipart/form-data" <form action="__URL__/up ...

  3. FTP文件上传以及获取ftp配置帮助类

    帮助类: using QSProjectBase; using Reform.CommonLib; using System; using System.Collections.Generic; us ...

  4. Java 使用 commons-fileupload 实现文件上传工具类

    依赖包 文件上传可以使用 Apache 文件上传组件, commons-fileupload, 它依赖于 commons-io commons-io.jar: https://repo1.maven. ...

  5. Liferay7 BPM门户开发之28: Portlet文件上传,及实体类同步更新上传

    抓住核心 . Liferay文件上传的核心就是使用UploadPortletRequest类 继承关系java.lang.Object extended byjavax.servlet.Servlet ...

  6. ServletFileUpload 文件上传

    import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadExcepti ...

  7. JavaWeb学习总结(五十)——文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  8. java web(四)文件上传与下载

     一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...

  9. JAVA-使用commos-fileupload实现文件上传与下载

    一文件的上传 实体类 在CODE上查看代码片派生到我的代码片 import java.sql.Timestamp; /** * * @Decription 文件上传实体类 * @author 刘楠 * ...

  10. 19、文件上传与下载/JavaMail邮件开发

    回顾: 一. 监听器 生命周期监听器 ServletRequestListener HttpSessionListener ServletContextListener 属性监听器 ServletRe ...

随机推荐

  1. Java反射学习-3 - 反射获取属性,方法,构造器

    package cn.tx.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ...

  2. wxpython中单选框的两种创建方式源码展示

    #coding=utf-8 import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self,None,-1, ...

  3. 模拟.net post请求属性

    这两天在做一个nodejs的爬虫项目,需要模拟post请求获得网站数据.遇到2个asp.net的网站,掉到坑里面,调试了好几天.总结一下过程. 一般我们模拟post请求的时候最重要的就是post请求里 ...

  4. 【记录】@Transactional

    参考链接:https://blog.csdn.net/nextyu/article/details/78669997 参考链接:https://www.xuebuyuan.com/3222458.ht ...

  5. 关于conda-新手必读

    一.管理conda 通过anaconda来安装python及python包,让你不必关心系统是否安装了一些依赖,如zlib等等,anaconda已经集成了这些依赖,可以方便的安装python 下载请点 ...

  6. Vue 学习之 vue-router2

    ---恢复内容开始--- 一.路由的安装: npm安装 npm install vue-router --save 执行命令完成vue-router的安装,并在package.json中添加了vue- ...

  7. 牛客ACM赛 B [小a的旅行计划 ]

    链接 B 小a的旅行计划 把\(n\)个数中选任意数分成\(a,b\)两个集合,集合无区别,要求不包含且有交,求方案数.\(n\leq 10^{13}\) 首先讨论\(a,b\)并集是否为全集: 若是 ...

  8. 前端每日实战:30# 视频演示如何用纯 CSS 创作一个晃动的公告板

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/wjZoGV 可交互视频教程 此视频 ...

  9. 美国知名Cloudflare网络公司遭中国顶尖黑客攻击

    最近中美贸易战愈演愈烈,美国知名Cloudflare网络公司的客户的分布式拒绝服务攻击今天在恶意流量方面达到了新的高度,黑客并袭击了该公司在欧洲和美国的数据中心.根据Cloudflare首席执行官马修 ...

  10. Java技术中如何使用keepalived实现双机热备

    Keepalived简介 Keepalived是Linux下一个轻量级别的高可用解决方案.高可用(High Avalilability,HA),其实两种不同的含义:广义来讲,是指整个系统的高可用行,狭 ...