Apache Commons FileUpload

Apache Commons FileUpload_第1张图片
文件上传

阅读原文请访问我的博客BrightLoong's Blog
Apache Commons FileUpload是用于解析上传文件的包。这里将其一些简单的特性和使用进行一个大概的介绍。

一.简介

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

二.简单使用

1.满足的条件

  • form表单使用POST请求,并且form表单的内容格式要定义成multipart/form-data格式

  • form表单内,要添加空间或者其他的比如:Uploadify插件

    File to upload:
    Notes about the file:

    to upload the file!

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 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 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 增加如下代码:。


  ...
  
    
      org.apache.commons.fileupload.servlet.FileCleanerCleanup
    
  
  ...

在使用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带进度条上传

你可能感兴趣的:(Apache Commons FileUpload)