关于common-fileupload的一些网络资料1

首先要了解上传的本质,首先上传需要在jsp页面的form标签中配置enctype="multipart/form-data"

因为这样配置后,在http请求发出时才会以2进制的方式去传输上传文件

 

当请求到达服务端后,在action我们的代码是

 

Java代码
  1. DiskFileItemFactory factory = new DiskFileItemFactory();   
  2. // 当文件大小超过300k时,就在磁盘上建立临时文件   
  3. factory.setSizeThreshold(300000);   
  4. //设计文件上传的临时目录   
  5. factory.setRepository(new File("D:<SPAN style="COLOR: #0000ff">//</SPAN>temp"));   
  6. ServletFileUpload upload = new ServletFileUpload(factory);   
  7. // 文件大小不能超过20M   
  8. upload.setSizeMax(20000000);  

在设定好了一系列参数后,我们就要开始主要的方法了

ServletFileUpload.parseRequest(Request  request)

 

Java代码 复制代码
  1. public List /* FileItem */ parseRequest(HttpServletRequest request)   
  2.   throws FileUploadException {   
  3.       return parseRequest(new ServletRequestContext(request));   
  4.   }  
  public List /* FileItem */ parseRequest(HttpServletRequest request)
    throws FileUploadException {
        return parseRequest(new ServletRequestContext(request));
    }

 

 

Java代码 复制代码
  1.  public List /* FileItem */ parseRequest(RequestContext ctx)   
  2.             throws FileUploadException {   
  3.         try {   
  4.             FileItemIterator iter = getItemIterator(ctx);//这个方法是相当重要的,在下面介绍   
  5.             List items = new ArrayList();   
  6.             FileItemFactory fac = getFileItemFactory();   
  7.             if (fac == null) {   
  8.                 throw new NullPointerException(   
  9.                     "No FileItemFactory has been set.");   
  10.             }   
  11.             while (iter.hasNext()) {   
  12.                 FileItemStream item = iter.next();   
  13.                 FileItem fileItem = fac.createItem(item.getFieldName(),   
  14.                         item.getContentType(), item.isFormField(),   
  15.                         item.getName());   
  16.                 try {   
  17. //将2个流copy,item.openStream()是request中的流,fileItem.getOutputStream()是准备向指定上传文件夹写文件的流   
  18. //fileItem.getOutputStream() 中就设定了临时文件的路径 下面将介绍   
  19.                    Streams.copy(item.openStream(), fileItem.getOutputStream(),   
  20.                             true);   
  21.                 } catch (FileUploadIOException e) {   
  22.                     throw (FileUploadException) e.getCause();   
  23.                 } catch (IOException e) {   
  24.                     throw new IOFileUploadException(   
  25.                             "Processing of " + MULTIPART_FORM_DATA   
  26.                             + " request failed. " + e.getMessage(), e);   
  27.                 }   
  28.                 if (fileItem instanceof FileItemHeadersSupport) {   
  29.                     final FileItemHeaders fih = item.getHeaders();   
  30.                     ((FileItemHeadersSupport) fileItem).setHeaders(fih);   
  31.                 }   
  32.                 items.add(fileItem);   
  33.             }   
  34. //返回FileItem的集合(关于FileItem的实现类,大家可以参考DiskFileItem)   
  35.             return items;   
  36.         } catch (FileUploadIOException e) {   
  37.             throw (FileUploadException) e.getCause();   
  38.         } catch (IOException e) {   
  39.             throw new FileUploadException(e.getMessage(), e);   
  40.         }   
  41.     }  
 public List /* FileItem */ parseRequest(RequestContext ctx)
            throws FileUploadException {
        try {
            FileItemIterator iter = getItemIterator(ctx);//这个方法是相当重要的,在下面介绍
            List items = new ArrayList();
            FileItemFactory fac = getFileItemFactory();
            if (fac == null) {
                throw new NullPointerException(
                    "No FileItemFactory has been set.");
            }
            while (iter.hasNext()) {
                FileItemStream item = iter.next();
                FileItem fileItem = fac.createItem(item.getFieldName(),
                        item.getContentType(), item.isFormField(),
                        item.getName());
                try {
//将2个流copy,item.openStream()是request中的流,fileItem.getOutputStream()是准备向指定上传文件夹写文件的流
//fileItem.getOutputStream() 中就设定了临时文件的路径 下面将介绍
                   Streams.copy(item.openStream(), fileItem.getOutputStream(),
                            true);
                } catch (FileUploadIOException e) {
                    throw (FileUploadException) e.getCause();
                } catch (IOException e) {
                    throw new IOFileUploadException(
                            "Processing of " + MULTIPART_FORM_DATA
                            + " request failed. " + e.getMessage(), e);
                }
                if (fileItem instanceof FileItemHeadersSupport) {
                    final FileItemHeaders fih = item.getHeaders();
                    ((FileItemHeadersSupport) fileItem).setHeaders(fih);
                }
                items.add(fileItem);
            }
//返回FileItem的集合(关于FileItem的实现类,大家可以参考DiskFileItem)
            return items;
        } catch (FileUploadIOException e) {
            throw (FileUploadException) e.getCause();
        } catch (IOException e) {
            throw new FileUploadException(e.getMessage(), e);
        }
    }

 

  

Java代码 复制代码
  1. public OutputStream getOutputStream()   
  2.       throws IOException {   
  3.       if (dfos == null) {   
  4.           File outputFile = getTempFile();   
  5.           dfos = new DeferredFileOutputStream(sizeThreshold, outputFile);   
  6.       }   
  7.       return dfos;   
  8.   }   
  9.   
  10.   protected File getTempFile() {   
  11.     //如果没设置临时目录,就用System.getProperty("java.io.tmpdir")   
  12.       if (tempFile == null) {   
  13.           File tempDir = repository;   
  14.           if (tempDir == null) {   
  15.               tempDir = new File(System.getProperty("java.io.tmpdir"));   
  16.           }   
  17.     //设计临时文件名   
  18.           String tempFileName =   
  19.               "upload_" + UID + "_" + getUniqueId() + ".tmp";   
  20.   
  21.           tempFile = new File(tempDir, tempFileName);   
  22.       }   
  23.       return tempFile;   
  24.   }  
  public OutputStream getOutputStream()
        throws IOException {
        if (dfos == null) {
            File outputFile = getTempFile();
            dfos = new DeferredFileOutputStream(sizeThreshold, outputFile);
        }
        return dfos;
    }

    protected File getTempFile() {
      //如果没设置临时目录,就用System.getProperty("java.io.tmpdir")
        if (tempFile == null) {
            File tempDir = repository;
            if (tempDir == null) {
                tempDir = new File(System.getProperty("java.io.tmpdir"));
            }
      //设计临时文件名
            String tempFileName =
                "upload_" + UID + "_" + getUniqueId() + ".tmp";

            tempFile = new File(tempDir, tempFileName);
        }
        return tempFile;
    }

 

 

Java代码 复制代码
  1. public FileItemIterator getItemIterator(RequestContext ctx)   
  2.   throws FileUploadException, IOException {   
  3.       return new FileItemIteratorImpl(ctx);   
  4.   }  
  public FileItemIterator getItemIterator(RequestContext ctx)
    throws FileUploadException, IOException {
        return new FileItemIteratorImpl(ctx);
    }

 

Java代码 复制代码
  1. FileItemIteratorImpl(RequestContext ctx)   
  2.               throws FileUploadException, IOException {   
  3.           if (ctx == null) {   
  4.               throw new NullPointerException("ctx parameter");   
  5.           }   
  6.   
  7.           String contentType = ctx.getContentType();  
  FileItemIteratorImpl(RequestContext ctx)
                throws FileUploadException, IOException {
            if (ctx == null) {
                throw new NullPointerException("ctx parameter");
            }

            String contentType = ctx.getContentType();
Java代码 复制代码

  1. //这就是为什么需要将请求写成multipart/form-data   
  2. //  public static final String MULTIPART = "multipart/"     
  3.             if ((null == contentType)   
  4.                     || (!contentType.toLowerCase().startsWith(MULTIPART))) {   
  5.                 throw new InvalidContentTypeException(   
  6.   "the request doesn't contain a "  + MULTIPART_FORM_DATA  + " or "   + MULTIPART_MIXED  + " stream, content type header is "+ contentType);   
  7.             }   
  8.   
  9.             InputStream input = ctx.getInputStream();   
  10.   
  11. //此处的sizeMax就是我们在action中set进去的值   
  12.             if (sizeMax >= 0) {   
  13.                 int requestSize = ctx.getContentLength();   
  14.                 if (requestSize == -1) {   
  15.                     input = new LimitedInputStream(input, sizeMax) {   
  16.                         protected void raiseError(long pSizeMax, long pCount)   
  17.                                 throws IOException {   
  18.                             FileUploadException ex =   
  19.                                 new SizeLimitExceededException(   
  20.                                     "the request was rejected because"   + " its size (" + pCount      + ") exceeds the configured maximum" + " (" + pSizeMax + ")",  pCount, pSizeMax);   
  21.                             throw new FileUploadIOException(ex);   
  22.                         }   
  23.                     };   
  24.                 } else {   
  25. //此处主要是判断上传文件的大小是否超过了设定值   
  26.                     if (sizeMax >= 0 && requestSize > sizeMax) {   
  27.                         throw new SizeLimitExceededException(   
  28.                                 "the request was rejected because its size ("  
  29.  + requestSize   + ") exceeds the configured maximum ("+ sizeMax + ")", requestSize, sizeMax);   
  30.                     }   
  31.                 }   
  32.             }  

    当返回了这个FileItem集合后,我们的代码如下

    Java代码 复制代码
    1. List<FileItem> items = getUploadFileIteams(request,pushObj,goUrl);   
    2.   
    3.     for (FileItem item : items) {   
    4.         File file = new File(realPath);   
    5.         item.write(file);   
    6.     }  
    List<FileItem> items = getUploadFileIteams(request,pushObj,goUrl);
    
    	for (FileItem item : items) {
    		File file = new File(realPath);
    		item.write(file);
    	}

    这里就将文件真正写到了服务器上

    再最后把item.write这个方法贴下吧,大家就更明白了

    Java代码 复制代码
    1. public void write(File file) throws Exception {   
    2.         if (isInMemory()) {   
    3.             FileOutputStream fout = null;   
    4.             try {   
    5.                 fout = new FileOutputStream(file);   
    6.                 fout.write(get());   
    7.             } finally {   
    8.                 if (fout != null) {   
    9.                     fout.close();   
    10.                 }   
    11.             }   
    12.         } else {   
    13.             File outputFile = getStoreLocation();   
    14.             if (outputFile != null) {   
    15.                 // Save the length of the file   
    16.                 size = outputFile.length();   
    17.               //看到下面的代码,大家就应该明白了吧   
    18.                 if (!outputFile.renameTo(file)) {   
    19.                     BufferedInputStream in = null;   
    20.                     BufferedOutputStream out = null;   
    21.                     try {   
    22.                         in = new BufferedInputStream(   
    23.                             new FileInputStream(outputFile));   
    24.                         out = new BufferedOutputStream(   
    25.                                 new FileOutputStream(file));   
    26.                         IOUtils.copy(in, out);   
    27.                     } finally {   
    28.                         if (in != null) {   
    29.                             try {   
    30.                                 in.close();   
    31.                             } catch (IOException e) {   
    32.                                 // ignore   
    33.                             }   
    34.                         }   
    35.                         if (out != null) {   
    36.                             try {   
    37.                                 out.close();   
    38.                             } catch (IOException e) {   
    39.                                 // ignore   
    40.                             }   
    41.                         }   
    42.                     }   
    43.                 }   
    44.             } else {   
    45.                 /*  
    46.                  * For whatever reason we cannot write the  
    47.                  * file to disk.  
    48.                  */  
    49.                 throw new FileUploadException(   
    50.                     "Cannot write uploaded file to disk!");   
    51.             }   
    52.         }   
    53.     }  

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值