Apache Commons FileUpload


文件上传


Apache Commons FileUpload是用于解析上传文件的包。这里将其一些简单的特性和使用进行一个大概的介绍。

一.简介

用于解析上传的文件,"Form-based File Upload in HTML"。也就是说,如果使用POST方法提交HTTP请求,并且使用内容类型“multipart / form-data”,则FileUpload可以解析该请求。

二.简单使用

1.满足的条件

  • form表单使用POST请求,并且form表单的内容格式要定义成multipart/form-data格式
  • form表单内,要添加空间<input type="file" name="">或者其他的比如:Uploadify插件

     <form method="POST" enctype="multipart/form-data" action="fup.cgi">
       File to upload: <input type="file" name="upfile"><br/>
       Notes about the file: <input type="text" name="note"><br/>
       <br/>
       <input type="submit" value="Press"> to upload the file!
     </form>

    2.具体使用

  • 使用前判断是否有上传文件的请求
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  • 简单的例子
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();

// Configure a repository (to ensure a secure temp location is used),默认会放在System.getProperty("java.io.tmpdir")
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Parse the request
List<FileItem> items = upload.parseRequest(request);
  • 加入一些控制的例子
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();

// Set factory constraints
//默认为10k,小于这个值的会放在内容中,否则放在设置的disk路径下
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory);

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Set overall request size constraint,最大上传文件
upload.setSizeMax(yourMaxRequestSize);

// Parse the request
List<FileItem> items = upload.parseRequest(request);

也可以一并配置多个属性

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(yourMaxMemorySize, yourTempDirectory);
  • 获取上传的文件信息
// Process a file upload
if (!item.isFormField()) {
    String fieldName = item.getFieldName();
    String fileName = item.getName();
    String contentType = item.getContentType();
    boolean isInMemory = item.isInMemory();
    long sizeInBytes = item.getSize();
    ...
}
  • 保存文件前获取文件的一些方式
// Process a file upload
if (writeToFile) {
    File uploadedFile = new File(...);
    item.write(uploadedFile);
} else {
    InputStream uploadedStream = item.getInputStream();
    ...
    uploadedStream.close();
}

OR

// Process a file upload in memory
byte[] data = item.get();
...

三.清理文件

仅仅适用于DiskFileItem,也就是说在上传前,文件被写入了临时文件,如果不再使用这些临时文件,则需要删除这些临时文件。DiskFileItemFactory有一个属性FileCleaningTracker,设置这个属性可以用来追踪删除临时文件。当这个临时文件不再被使用时将会被立即删除,更精确的说是这个文件对象被垃圾收集器回收时,FileCleaningTracker将启动收割者线程(reaper thread)自动删除这个临时文件。 为了确保这个
后台线程在它不再被需要时被停止,在 servlet 环境里,我们通过一个名叫 FileCleanerCleanup 的 s
ervlet 上下文监听器,在web应用关闭时调用FileCleaningTracker.exitWhenFinished()来终止收割机线
程。在servlet环境中,使用 FileCleanerCleanup,FileCleanerCleanup提供了FileCleaningTracker的一个实例,要让FileCleanerCleanup监听器工作,你需要在 web.xml 增加如下代码:。

<web-app>
  ...
  <listener>
    <listener-class>
      org.apache.commons.fileupload.servlet.FileCleanerCleanup
    </listener-class>
  </listener>
  ...
</web-app>

在使用FileCleanerCleanup,应该像下面这样创建DiskFileItemFactory

public static DiskFileItemFactory newDiskFileItemFactory(ServletContext context,
                                                         File repository) {
    //FileCleaningTracker类,这个类用于跟踪要删除的文件
    FileCleaningTracker fileCleaningTracker
        = FileCleanerCleanup.getFileCleaningTracker(context);
    DiskFileItemFactory factory
        = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD,
                                  repository);
    factory.setFileCleaningTracker(fileCleaningTracker);
    return factory;
}

四.上传进度

下面是一个创建进度监听的一个例子

//Create a 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);

但是这样会存在问题,有可能会被频繁的调用而造成性能问题。

//Create a progress listener
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.");
       }
   }
};

如果想在页面展示,可以自己实现一个ProgressListener接口,将进度的相关信息放在session中。通过ajax之类的进行调用。具体可以参照博客-- Common-FileUpload带进度条上传

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值