2012-03-03 17 views
5

Tengo problemas con la carga de archivos HTTP con archivos de más de 2GB. Tanto el servidor como el cliente tienen 64 bits, por lo que no debe haber restricciones de 2 GB desde la perspectiva del sistema. Hice lo siguiente:Tomcat 6.0 Carga de archivos grandes (> 2 GB)

  1. En Apache LimitRequestBody = 0 (http://httpd.apache.org/docs/2.0/mod/core.html#LimitRequestBody)
  2. En Tomcat Conector MaxPostSize = 0 (http://tomcat.apache.org/tomcat-5.5-doc/config/ajp.html)

estoy usando Apache Commons carga de archivos. También traté de establecer el tamaño máximo de archivo usando el método ServerFileUpload setMaxFileSize.

Puedo cargar archivos de menos de 2GB (probé el archivo de 1.88GB con éxito). Por favor dirígeme, ¿qué es lo que echo de menos aquí?

Para ser más específico ServletFileUpload.parseRequest método devuelve 0 FileItems al cargar archivos de gran tamaño

Aquí está el fragmento de código:

if (isMultipartForm()) { 
try { 
    DiskFileItemFactory factory = new DiskFileItemFactory(); 
    factory.setSizeThreshold(SIZE_THRESHOLD);//SIZE_THRESHOLD = 4MB 
    ServletFileUpload upload = new ServletFileUpload(factory); 
     //upload.setFileSizeMax(3000000000L); Tried this too 
    upload.setProgressListener(progressListener); 
    items = upload.parseRequest(request); 
    if(items != null && items.size() == 0) 
    return new CommandResultSet(false, "NoItemsFoundInRequest"); 
    return new CommandResultSet(true, "" + ((items!=null) ? items.size() : "")); 
} catch(FileUploadException e) { 
    e.printStackTrace(); 
    System.out.println("Exception in MultipartFormManager. Can not parse request.");  
    return new CommandResultSet(false, e.getMessage()); 
    } 
} 
+0

¿Cómo está utilizando exactamente la biblioteca apache? Muéstranos el código. –

+0

Debe probar su servidor con una herramienta de línea de comando sin formato como "wget" para excluir cualquier problema del servidor: tamaño de archivo codificado como entero en algún lugar de la pila, límite del sistema de archivos ... –

+0

¿Cuáles son los síntomas de su problema? La transferencia está bloqueada o detenida? Cualquier rastro de la pila del servidor? ¿Qué pasa con la actividad "en el cable"? Mírelo con wireshark. –

Respuesta

1

ciertamente puede nuevo mal, pero no he encontrado que incluso el 64 bit Los navegadores manejan cargas de más de 2 GB. El problema no es el servidor, sino el navegador. Descubrirá de forma bastante extraña que la mayoría de los navegadores modernos descargarán felizmente archivos de más de 2 GB de un servidor estándar, sin necesidad de una configuración especial.

+0

¿Podría proporcionar algún enlace que respalde su respuesta? Solo pude encontrar esto (http://www.motobit.com/help/ScptUtl/pa33.htm) pero no estaba seguro. – Sunil

+0

Hola, gracias por tu referencia, no estaba al tanto. Mis comentarios se basan en la experiencia con Apache 2.2, IE y Firefox en los últimos años. Es bueno escuchar sobre Chrome, no lo había probado en mucho tiempo. Es probable que Flash tampoco te ayude, tienes que enviar los datos en pedazos relativamente pequeños en relación con un archivo tan grande y las cosas se vuelven mucho más lentas. Todos los servicios comerciales de los que tengo conocimiento no soportan más de 2GB, a menos que use el software de su cliente. Con la información correcta del encabezado, no veo ningún motivo por el que Apache no pueda manejar estos archivos. Es la desventaja de los navegadores. – Mike

+0

aquí está el [enlace a la entrada del error de mozilla] (https://bugzilla.mozilla.org/show_bug.cgi?id = 215450) –

0

Si espera cargas de archivos de esos tamaños, no confiaría en una carga directa del navegador. Un applet de Java o tal vez incluso un archivo de Flash (no estoy seguro si es posible, no una persona de Flash) sería mi recomendación, por lo que puede dividir los archivos en fragmentos. Si la carga se interrumpe, puede reanudar desde donde se dejó por última vez.

+0

Entiendo que no es confiable, pero hay menos solicitudes de ese tamaño, por lo que si al menos puedo manejar esas solicitudes sería genial. – Sunil

0
Jsp code : 
<script src="../lib/app/configurator.data.ajax.js" type="text/javascript"></script> 
<script src="../lib/ui/jquery.fileupload.js"></script> 
<html> 

<script language="Javascript"> 
var varb = ''; 
var test = 0; 
var count = 1; 
$(function() { 
var maxChunkSize = 30000000; //SET CHUNK SIZE HERE 
var your_global_var_for_form_submit = ''; 

var params = { 
     year: threeDSelectedYear, 
     series: threeDSelectedSeries 
}; 
/*File upload bind with form, 'fileupload' is my form id. As sumit triggers 
    for file ulaod will submit my form*/ 
/* replaceFileInput: true, */ 
$('#fileupload').fileupload({ 
maxChunkSize: maxChunkSize, 
url: efccustom.getEfcContext()+'upload/uploadZip?year='+threeDSelectedYear+'&series='+threeDSelectedSeries,    //URL WHERE FILE TO BE UPLOADED 
    error: function (jqXHR, textStatus, errorThrown) { 
    // Called for each failed chunk upload 
     $(".fileupload-loading").html(""); 
     $('.ANALYZE_DIALOG').dialog("close");  
    }, 

    success: function (data, textStatus, jqXHR) { 
    /*This event will be called on success of upload*/ 
    count = parseInt($('#counter').val()) + 1; 
    $('#counter').val(count); 

    $('#ttk').val(count); 
    data.ttk = 7; 
    console.log(" count ",count , data); 
    }, 

    submit: function (e, data) { 
    /*This event will be called on submit here i am 
        adding variable to form*/ 
    //console.log($('#zip_uploaded_file').val());  

    //console.log(data.originalFiles[0].name);    
    test = data.originalFiles[0]; 
    $('#fname').val(data.originalFiles[0].name); 
    $('#trequests').val(Math.ceil(data.originalFiles[0].size/maxChunkSize)); 
    $('#counter').val('1'); 
    }, 

    progress: function (e, data) { 
    /*PROGRESS BAR CODE WILL BE HERE */ 
     $(".fileupload-loading").html('<img src="../public/themeroller/images/throbber.gif" alt="Uploading Please Wait..." title="Uploading Please Wait...." />');  
    }, 

    add: function (e, data) { 
    $('.browsedFileName').html(data.originalFiles[0].name); 
    your_global_var_for_form_submit = data; 
    }, 

    done: function (e, data) { 

     ajaxcall.Data._get('upload/extractZipNCreateJson',params,function(data2) { 
      alert("file upload success "); 
      $(".fileupload-loading").html(""); 
      $('.ANALYZE_DIALOG').dialog("close"); 
     }); 


    } 

}); 
/*This is my button click event on which i am submitting my form*/ 
    $('#button').click(function(){ 
    your_global_var_for_form_submit.submit(); 
    }); 
}); 
</script> 

<html> 

<body> 


<form id="fileupload" enctype="multipart/form-data"> 
<div class="row fileupload-buttonbar"> 
<div class="span7"> 
<!--<input type="file" name="files" id="file" /> --> 

<input type="file" id="zip_uploaded_file" name="zip_uploaded_file" /> 
<input type="hidden" name="counter" id="counter" value="1" /> 
<input type="hidden" name="fname" id="fname" value="" /> 
<input type="hidden" name="trequests" id="trequests" value="1" /> 

<input type="hidden" name="ttk" id="ttk" value="1" /> 
<input type="button" id="button" name="button" value="submit" /> 
<span class='browsedFileName'></span> 
</div> 
</div> 
<!-- The loading indicator is shown during file processing --> 
<div class="fileupload-loading"></div> 
</form> 
</body> 


Controller COde : 
@RequestMapping(value = "/uploadZip", method = RequestMethod.POST, consumes = "multipart/form-data") 
    @ResponseBody 
    public ResponseEntity<String> 
    uploadZip(HttpServletRequest request, HttpServletResponse response) 
      throws IOException, IllegalArgumentException { 
     try {  
     String year = request.getParameter("year"); 
     String series = request.getParameter("series"); 
     log.info(" year " + year + " series " + series); 
     boolean isMultipart = ServletFileUpload.isMultipartContent(request); 
     if (isMultipart) { 

      FileItemFactory factory = new DiskFileItemFactory(); 
      ServletFileUpload upload = new ServletFileUpload(factory); 
      List items = upload.parseRequest(request); 
      Iterator iterator = items.iterator(); 

      HttpSession session = request.getSession(); 
      UserContext userContext = (UserContext) session 
        .getAttribute(ApplicationConstant.USER_CONTEXT); 
      String userName = userContext.getUser(); 
      String workSpaceInUse = userContext.getCurrentWorkSpace();   
      FileItem item = null; 
      boolean fileNotExistFlag; 
      String fileExtension; 
      while (iterator.hasNext()) { 
       item = (FileItem) iterator.next(); 

       String content = item.getContentType(); 
       log.info(" content "+content); 
       log.info(" File Type Getting Uploaded :"+content); 
       if (!item.isFormField()) { 
      /* Here in IOUtils the Third Parameter true tells that the small chunks of data that comes need to be added to the same File */ 
      IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(new File(threeDPath+"/"+year+"/"+series+"/"+uploadZipFileName),true));    
       } 
      } 
      return null; 
     } 
     } 
     catch(Exception e) { 
      return handleError(new RuntimeException("Unexpected error while uploading ZIP", e)); 
     } 
     return null; 
    } 
1

Si está utilizando común fileupload 1.1 o viejo, entonces no puede cargar morethan (1.9888) ~ 2 GB. El problema aquí es que este jar llama a un método llamado getContentLength que es de tipo int, por lo que su solicitud solo puede manejar el tamaño hasta Integer.MAX_VALUE. En la última versión de common-fileupload como 1.3, esto se solucionó. Espero que esto ayude.

Cuestiones relacionadas