`

Apache common-fileupload用户指南

    博客分类:
  • J2SE
阅读更多
    http://www.cnblogs.com/ybase/archive/2011/11/15/2249298.html
使用FILE UPLOAD

File Upload有很多不同的使用方式,取决于你的应用程序,最简单的方式是使用一个单独的方法来转换servlet请求,然后处理这些像你的应用发出请求的项。在另一个面,你可能需要决定对哪个项执行完全控制以保存它。比如:你可能会决定把内容保存到数据库中。

这里,我们将描述File Upload的原理,并举例说明一些较为简单--最常使用的模式,关于File Upload的定制,可以在其他其他位置。

File Upload依赖于Commons IO,请确保你的classpath里有对于版本的jar包(相关页面有提及)。

如何工作

一个file upload请求包含一组根据RFC 1867编码的已排序的项目,“基于HTML表单的文件上传”。File Upload能够转换一个请求然后为你的应用程序提供一组单一上传的项目。每个这样的项目都实现了FileItem接口,不太在乎如何具体实现。

这一页介绍了commons fileuplaod库的传统API,传统的API是一个方便的方法。但是,为了最终性能着想,你可能更喜欢使用Streaming API。

每一个文件项都有一些你的应用程序可能感性趣的属性。比如,所有项都有一个名字和内容类型,并且提供了一个输入流去访问它的数据。另一方面,你可能需要使用不同的方式去处理这些项,依据该项是否一个正则的表单元素(数据是否来自于一个传统的文本框或者类似的表单元素),或者一个上传的文件。文件项接口提供了方法去实现这个检测,以及相应的方式访问它们的数据。

Servlet和门户组件

从1.1版开始,FileUpload在servlet和门户组件两种环境里提供文件上传请求。用法在两种环境里差不多,所以这篇文档余下的部分只涉及servlet环境。

如果你正在创建一个门户组件应用,你应该区分下面两点和这篇文档的不同之处。

在任何地方看到ServletFileUpload类的参考文献,请用PortletFileUpload类来代替。

在任何地方看到HttpServletRequest 类的参考文献,请用ActionRequest类来代替。

解析请求

当然,在你操作上传组件之前,你需要解析请求自身。确保请求实际上是一个文件上传请求很简单,File Upload的提供了一个静态方法使它非常简单。

// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);

现在我们可以把请求解析成它的组成项。

最简单的情况

最简单的使用情况如下:

只要上传项足够小,那就应该保存在内存里。

大的项应该被写入硬盘的临时文件文件。

非常大的请求应该被阻止上传。

你的应用默认设置可以保存在内存中的最大大小的项目,最大可上传的请求,以及临时存放上传文件的临时目录是可被接受的。

没有比下面更简单的处理请求的方法了:

// 为基于硬盘文件的项目集创建一个工厂

FileItemFactory factory = new DiskFileItemFactory();
// 创建一个新的文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析请求
List items = upload.parseRequest(request);

以上就是所有需要做的。真的!

请求被解析后,你会提到一些由实现了FileItem接口的项目组成的集合。我们会在下面讨论这此项目。

运用更多控制

如果你的使用情况和最简单的使用情况差不多,如上所述,但是,如果你需要更多的控制的话,可以选择定义上传处理器和项目工厂的行为,这是委简单的。

// 为基于硬盘文件的项目集创建一个工厂

FileItemFactory factory = new DiskFileItemFactory();
// 设置工厂的约束条件
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory);
// 创建一个新的文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);

// 设置可请求在最大可上传数据量
upload.setSizeMax(yourMaxRequestSize);
// 解析请求
List items = upload.parseRequest(request);

当然,每个配置都可心独立存在,不过你可以一次性配置工厂的所有配置项,使用一个替代的构造方法可以做到这点,像这样:

// 为基于硬盘文件的项目集创建一个工厂

DiskFileItemFactory factory = new DiskFileItemFactory(
yourMaxMemorySize, yourTempDirectory);

如果你需要相比于解析请求更多的控制,像把项目存到其他地方,比如存到数据库,你需要阅读customizing File Upload。

处理上传项目

当完成请求解析后,你会得到一个由你想要处理的文件项组成的集合。大部分情况下,你会想要把使用文件上传的上传的项处理方法区别于和常规表单处理,你需要这样做:
// 处理上传项目
Iterator iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();

    if (item.isFormField()) {
        processFormField(item);
    } else {
        processUploadedFile(item);
    }
}

对于一个正常的表单项,你只会关心它的name,以及对应的字符串值。和你的预期一样,访问上传项目也非常简单。
// 处理一个正常表单
if (item.isFormField()) {
    String name = item.getFieldName();
    String value = item.getString();
    ...
}

对于一个文件上传项,在你处理它的内容之前,你可能会想要知道几件事情。这里有一个关于你可能感兴趣的一些方法的例子。
// 处理上传项目
if (!item.isFormField()) {
    String fieldName = item.getFieldName();
    String fileName = item.getName();
    String contentType = item.getContentType();
    boolean isInMemory = item.isInMemory();
    long sizeInBytes = item.getSize();
    ...
}

对于上传的文件,你通常不会想把它放到内存中,除非它很小,或者你没有其它可替代的方法。恰恰相反,你会把文件当成流来处理,并把整个文件存放到最终位置。File Upload提供了简单的方法来实现这两种处理。
// 处理上传项目
if (writeToFile) {
    File uploadedFile = new File(...);
    item.write(uploadedFile);
} else {
    InputStream uploadedStream = item.getInputStream();
    ...
    uploadedStream.close();
}

注意,在FileUpload的默认实现里,如果数据已经在临时文件中,write方法会试图更改存放到指定目的地的文件名。其实数据的复制只会在由于某种原因重命名失败的时候才会成功,或者当数据在内存中已经存在的时候。

如果你需要访问内存中的数据,你仅仅只需要使用get()方法将数据获取并保存到一个字节数组中。
// 处理内存中的上传项
byte[] data = item.get();
...

资源清理

本节只在你使用DiskFileItem时适用。换句话说,它只适用于你在处理上传项目之前将它们写入临时文件的情况。这些临时文件在不使用(更准确的说,是如果java.io.File的类似实例被垃圾回收了。)的情况下会自动删除。org.apache.commons.io.FileCleaner类会默默的完成这个操作,它会启动一个收割机线程。

这个收割机线程在不使用的时候应该关闭。在一个servlet环境里,使用一个特殊的servlet context listener FileCleanerCleanup来完成这件事情。为了让它起作用,需要在你的web.xml里面加入下面的代码片段:
<web-app>
  ...
  <listener>
    <listener-class>
      org.apache.commons.fileupload.servlet.FileCleanerCleanup
    </listener-class>
  </listener>
  ...
</web-app>

创建一个硬盘文件项工厂

FileCleanerCleanup提供了一个org.apache.commons.io.FileCleaningTracker的实例,在创建org.apache.commons.fileupload.disk.DiskFileItemFactory的时候一定要使用这个实例。下面的代码里的方法调用实现了这个步骤。
    public static DiskFileItemFactory newDiskFileItemFactory(ServletContext context,
                                                             File repository) {
        FileCleaningTracker fileCleaningTracker
            = FileCleanerCleanup.getFileCleaningTracker(context);
        DiskFileItemFactory factory
            = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD,
                                      repository);
        factory.setFileCleaningTracker(fileCleaningTracker);
        return factory;
    }

禁用的清除临时文件

要禁用跟踪临时文件,你要设置FileCleaningTracker为空。因为置空,创建的文件将不会再被跟踪,特别说明,它们也不会再被自动删除。

与病毒扫描器互动

病毒扫描器可能和使用了FileUpload的应用程序运行在同一系统上,这可能会导致web容器执行一些异常的行为。这一节介绍了一些你可能会遇到的异常行为,并且提供了一些方法去处理这些问题。

FileUpload的默认实现会将超出临界值的数据写入硬盘。一旦这个文件关闭,系统上的任何病毒扫描器就是被唤醒并且检测这个文件,可能会隔离这个文件--将它移动到不会引起问题的特定地方。这个,当然,对于程序开发员来说,由于上传的文件项目将不再访问,会让程序员感到奇怪。而另一方面,处于临界值之下的数据会被加载到内存中,因此不会被病毒扫描器检测。这允许病毒以某种形式保存在内存中(尽管它曾经被写入到硬盘中,然后被病毒扫描器扫描并隔离)。

一种常用的解决办法是在系统上设置一个目录来专门保存上传的文件。并且设置病毒扫描器忽略这个目录。这样可以保证应用下的文件不会被分离,但是会分离程序开发人员和病毒扫描的责任关系。可以提供一个扩展的处理程序来执行病毒扫描,将无毒的,被杀过毒的文件移动到特定的位置,或者集成一个病毒扫描系统到应用内部。

关于扩展一个处理以及集成一个扫描系统到应用内部的详细内容超出了本文档的范围。

上传进度

如果希望上传非常大的文件,你需要抽向你的用户提供反馈,已经上传了多少。HTML页面允许通过返回一个multipart/replace响应来实现一个进度条,或其它类似的东西。

可以通过使用一个progress listener来供应一个进度条:
//创建一个进度条监听器
ProgressListener progressListener = new ProgressListener(){
   public void update(long pBytesRead, long pContentLength, int pItems) {
       System.out.println("We are currently reading item " + pItems);
       if (pContentLength == -1) {
           System.out.println("So far, " + pBytesRead + " bytes have been read.");
       } else {
           System.out.println("So far, " + pBytesRead + " of " + pContentLength
                              + " bytes have been read.");
       }
   }
};
upload.setProgressListener(progressListener);

帮你自己一个忙,像上面一样实现你的第一个进度条监听器,因为它向你展示了一个缺陷:进步条使用非常频繁。依赖于servlet引擎和其他环境工厂,它可能会被任何网络数据包调用。换句话说,你的进度条监听器会引起性能问题!可能是一个典型的解决方案,是减少进步条的活动数。比如,只有当上传了1兆字节的时候才反馈给用户:
//创建一个进度监听器
ProgressListener progressListener = new ProgressListener(){
   private long megaBytes = -1;
   public void update(long pBytesRead, long pContentLength, int pItems) {
       long mBytes = pBytesRead / 1000000;
       if (megaBytes == mBytes) {
           return;
       }
       megaBytes = mBytes;
       System.out.println("We are currently reading item " + pItems);
       if (pContentLength == -1) {
           System.out.println("So far, " + pBytesRead + " bytes have been read.");
       } else {
           System.out.println("So far, " + pBytesRead + " of " + pContentLength
                              + " bytes have been read.");
       }
   }
};

下一步是什么?

希望这篇文章能够给你在应用中使用File Upload提供了一个好的想法。想要更多关于这篇文章中提到的方法的资料,和其它方法一样,你需要参考JavaDocs。

这里描述的使用应满足大部分的文件上传的需要。然而,如果你有更复杂的要求,FileUpload还能以其灵活的定制帮助你。
分享到:
评论

相关推荐

    commons-fileupload文档及源代码.rar

    `common_fileupload详解.doc`文档应该提供了关于库的详细使用指南、API参考和示例代码。通过阅读文档,你可以快速掌握如何在项目中集成和使用`commons-fileupload`。 总的来说,Apache Commons FileUpload库极大地...

    apache common系列包的作用以及帮助文档

    - **用户指南**:解释了如何在实际项目中使用 Commons 类库,提供示例代码和最佳实践。 - **FAQ**:常见问题解答,解决在使用 Commons 类库时遇到的常见问题。 - **Mailing List** 和 **论坛**:开发者交流平台,...

    ssh综合配置文件

    ### SSH综合配置文件:JavaEE中的SSH整合指南 在JavaEE开发中,SSH(Struts、Spring、Hibernate)是常见的企业级应用开发框架组合。本文将深入探讨如何在项目中整合这三大框架,以实现更高效、灵活的开发流程。 ##...

    Struts2开发指南

    - Apache Jakarta Common项目的`ognl-VERSION.jar`(OGNL引擎)、`freemarker-VERSION.jar`(Freemarker模板引擎)、`xwork-VERSION.jar`等。 - 其他插件如`struts2-xxx-plugin-VERSION.jar`。 - **环境搭建步骤*...

    [AB PLC例程源码][MMS_044666]Translation N-A.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    kolesar_3cd_01_0716.pdf

    kolesar_3cd_01_0716

    latchman_01_0108.pdf

    latchman_01_0108

    matlab程序代码项目案例:matlab程序代码项目案例MPC在美国高速公路场景中移动的车辆上的实现.zip

    matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    pimpinella_3cd_01_0716.pdf

    pimpinella_3cd_01_0716

    petrilla_01_0308.pdf

    petrilla_01_0308

    [AB PLC例程源码][MMS_041452]Speed Controls in Plastic Extrusion.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    强化学习驱动下DeepSeek技术创新及其对AI发展的影响

    内容概要:本文档由张卓老师讲解,重点探讨DeepSeek的技术革新及强化学习对未来AI发展的重要性。文章回顾了AI的历史与发展阶段,详细解析Transformer架构在AI上半场所起到的作用,深入介绍了MoE混合专家以及MLA低秩注意机制等技术特点如何帮助DeepSeek在AI中场建立优势,并探讨了当前强化学习的挑战和边界。文档不仅提及AlphaGo和小游戏等成功案例来说明强化学习的强大力量,还提出了关于未来人工通用智能(AGI)的展望,特别是如何利用强化学习提升现有LLMs的能力和性能。 适用人群:本资料适宜对深度学习感兴趣的研究人员、开发者以及想要深入了解人工智能最新进展的专业人士。 使用场景及目标:通过了解最新的AI技术和前沿概念,在实际工作中能够运用更先进的工具和技术解决问题。同时为那些寻求职业转型或者学术深造的人提供了宝贵的参考。 其他说明:文中提到了许多具体的例子和技术细节,如DeepSeek的技术特色、RL的理论背景等等,有助于加深读者对于现代AI系统的理解和认识。

    有师傅小程序开源版v2.4.14+前端.zip

    有师傅小程序开源版v2.4.14 新增报价短信奉告 优化部分细节

    [AB PLC例程源码][MMS_047333]Motor Sequence Starter with timers to start.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    商城二级三级分销系统(小程序+后台含源码).zip

    商城二级三级分销系统(小程序+后台含源码).zip

    li_3ck_01b_0918.pdf

    li_3ck_01b_0918

    nicholl_3cd_01_0516.pdf

    nicholl_3cd_01_0516

    1995-2022年 网络媒体关注度、报刊媒体关注度与媒体监督相关数据.zip

    媒体关注度是一个衡量公众对某个事件、话题或个体关注程度的重要指标。它主要反映了新闻媒体、社交媒体、博客等对于某一事件、话题或个体的报道和讨论程度。 媒体监督的J-F系数(Janis-Fadner系数)是一种用于测量媒体关注度的指标,特别是用于评估媒体对企业、事件或话题的监督力度。J-F系数基于媒体报道的正面和负面内容来计算,从而为公众、研究者或企业提供一个量化工具,以了解媒体对其关注的方向和强度。 本数据含原始数据、参考文献、代码do文件、最终结果。参考文献中JF系数计算公式。 指标 代码、年份、标题出现该公司的新闻总数、内容出现该公司的新闻总数、正面新闻数全部、中性新闻数全部、负面新闻数全部、正面新闻数原创、中性新闻数原创、负面新闻数原创,媒体监督JF系数。

    [AB PLC例程源码][MMS_040315]Double INC and Double DEC of INT datatype.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_047773]Convert Feet to Millimeters.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

Global site tag (gtag.js) - Google Analytics