Commons FileUpLoad

FileUpload组件将页面提交的所有元素(普通form表单域,如text和文件域file)都看作一样的FileItem,这样上传页面提交的request请求也就是一个FileItem的有序组合,FileUpload组件可以解析该request,并返回一个一个的FileItem。而对每一个FileItem,FileUpload组件可以判断出它是普通form表单域还是文件file域,从而根据不同的类型,采取不同的操作--如果是表单域,就读出其值,如果是文件域,就保存文件到服务器硬盘上或者内存中。

 

 

1.对一个HttpRequest请求,我们要判断该请求是否是文件上传的请求.

先确保该请求是一个文件上传的请求

    boolean isMultipart = ServletFileUpload.isMultipartContent(request);

 

2. 最简单的使用场景:

      上传的文件只要是合理的小,就保存在内存中。

      文件过大,应该写入硬盘的临时文件

      不允许上传过大的文件。

 

       // 创建文件处理工厂,它用于生成 FileItem 对象。

    DiskFileItemFactory factory = new DiskFileItemFactory(); 

       //  创建文件上传处理器

       ServletFileUpload upload = new ServletFileUpload(factory);

       //  处理请求

       List /* FileItem */ items = upload.parseRequest(request);

       请求处理的结果是一个文件列表,每一项实现FileItem接口。

 

3. 更多的控制:你可以简单的定制上传处理器或者文件处理工厂。

 

     DiskFileItemFactory factory = new DiskFileItemFactory();

     设置最多只允许在内存中存储的数据,单位:字节

     factory.setSizeThreshold(yourMaxMemorySize);

     设置一旦文件大小超过内存存储的值时,数据存放在硬盘的临时目录(默认可以不用设置)  

     factory.setRepository(yourTempDirectory);

     设置允许用户上传文件大小,单位:字节

     ServletFileUpload upload = new ServletFileUpload(factory);

     upload.setSizeMax(yourMaxRequestSize);

     List /* FileItem */ items = upload.parseRequest(request);

 

4. 处理上传的项目

    一旦完成分析,你就会获得要处理的项目列表。通常情况下,你会将普通字段和文件字段区别开。

对每个Item的处理要考虑是标准的form表单域还是上传文件file域,然后做不同的处理.

   Iterator iter = items.iterator();

   while (iter.hasNext()) {

     FileItem item = (FileItem) iter.next();

 

     if (item.isFormField()) {

         processFormField(item);

     } else {

         processUploadedFile(item);

     }

    }

 

    如果是普通字段,大部分情况只对它的项目名称以及字符串值感兴趣。

   if (item.isFormField()) {

     String name = item.getFieldName();

    String value = item.getString();

    ...

   }

 

 

 实际上,对于一个上传的文件,我们一般不会把它包存在内存中,除非它足够小。我们一般是把它保存到硬盘上,使用以下方法就可以将上传的文件保存到服务器硬盘上了:

 

   if (writeToFile) {

     File uploadedFile = new File(...);

     item.write(uploadedFile);

   } else {

     InputStream uploadedStream = item.getInputStream();

     ...

     uploadedStream.close();

   }  

 

 

 注意:在FileUpload的默认实现中,如果数据已经在临时文件中,write()会尝试重命名文件到指定的目录。

如果你确定要访问内存中的上传数据,只要调用get()方法来获得bytes数组类型的数据。

// Process a file upload in memory

byte[] data = item.get();

 

5. 资源清理

    如果在处理之前,你把上传的文件保存在临时文件中。如果这些临时文件没用了,需要自动删除。这是靠一个不断重复的线程进行处理的 。  org.apache.commons.io.FileCleaner  需要在web.xml中增加以下代码

 

<web-app>

  ...

   <listener>

     <listener-class>

       org.apache.commons.fileupload.servlet.FileCleanerCleanup

     </listener-class>

   </listener>

  ...

</web-app>

 

 

6. 创建DiskFileItemFactory

   FileCleanerCleanup提供一个org.apache.commons.io.FileCleaningTracker的实例。在创建

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;

    }

 

表单中设置 enctype="multipart/form-data" 很重要。 
处理上传jsp文件 
判断表单是否是Multipart类型的。这里可以直接对request进行判断

  1. if (ServletFileUpload.isMultipartContent(request)) {  
  2.     // 创建文件处理工厂,它用于生成 FileItem 对象。   
  3.     DiskFileItemFactory factory = new DiskFileItemFactory();   
  4.      设置文件的缓存路径  
  5.        String tempdir =this.getServletContext().getRealPath("/upload/temp");      
  6.      java.io.File d = new java.io.File(savedir);  
  7.         if(!d.exists()){  
  8.          d.mkdirs();  
  9.         }  
  10.        
  11.     factory.setSizeThreshold(1024*1024); // 设置最多只允许在内存中存储的数据,单位:字节  
  12.     factory.setRepository(d); // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录(默认可以不用设置)  
  13.   
  14.     // Create a new file upload handler  
  15.     ServletFileUpload upload = new ServletFileUpload(factory);  
  16.     // 设置允许用户上传文件大小,单位:字节  
  17.     upload.setSizeMax(yourMaxRequestSize);  
  18.     //上传文件,并解析出所有的表单字段,包括普通字段和文件字段  
  19.     List  items = upload.parseRequest(request);   
  20.          //下面对每个字段进行处理,分普通字段和文件字段  
  21.    Iterator it = items.iterator();  
  22.    while(it.hasNext()){  
  23.     FileItem fileItem = (FileItem) it.next();  
  24.     //如果是普通字段  
  25.     if(fileItem.isFormField()){  //是普通的字段  
  26.      System.out.println(fileItem.getFieldName() + "   " + fileItem.getName() + "   " + new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));  
  27.     fileItem.getFieldName();//得到字段name属性的值  
  28.     fileItem.getName();//得到file字段的文件名全路径名,如果不是file字段,为null  
  29.     fileItem.getString();//得到该字段的值,默认的编码格式  
  30.     fileItem.getString("UTF-8");//指定编码格式  
  31.     }else{//文件字段  
  32.          System.out.println(fileItem.getFieldName() + "   " +  
  33.         fileItem.getName() + "   " +//得到file字段的文件名全路径名  
  34.         fileItem.isInMemory() + "    " +//用来判断FileItem类对象封装的主体内容是存储在内存中,还是存储在临时文件中,如果存储在内存中则返回true,否则返回false  
  35.         fileItem.getContentType() + "   " +//文件类型  
  36.         fileItem.getSize());          //文件大小  
  37.   
  38.        //什么东西都有了 ,想怎么处理都可以了  
  39.      //保存文件,其实就是把缓存里的数据写到目标路径下  
  40.      if(fileItem.getName()!=null && fileItem.getSize()!=0){  
  41.       File fullFile = new File(fileItem.getName());  
  42.       File newFile = new File("c:/temp/" + fullFile.getName());  
  43.       try {  
  44.        fileItem.write(newFile);  
  45.       } catch (Exception e) {  
  46.        e.printStackTrace();  
  47.       }  
  48.      }else{  
  49.       System.out.println("文件没有选择 或 文件内容为空");  
  50.      } 

 

 

你可能感兴趣的:(apache,jsp,Web,servlet)