2012-03-03 38 views
5

Tôi đang gặp sự cố với tải lên tệp HTTP với tệp lớn hơn 2GB. Cả máy chủ và máy khách đều có 64 bit nên không được giới hạn 2GB từ góc độ hệ thống. Tôi đã làm như sau:Tải lên tệp lớn Tomcat 6.0 (> 2 GB)

  1. Trong Apache LimitRequestBody = 0 (http://httpd.apache.org/docs/2.0/mod/core.html#LimitRequestBody)
  2. Trong Tomcat nối maxPostSize = 0 (http://tomcat.apache.org/tomcat-5.5-doc/config/ajp.html)

Tôi đang sử dụng apache upload commons tập tin. Tôi cũng đã cố gắng đặt kích thước tệp tối đa bằng phương pháp ServerFileUpload setMaxFileSize.

Tôi có thể tải lên tệp dưới 2 GB (tôi đã thử thành công tệp 1.88GB). Hãy chỉ đạo cho tôi, tôi đang thiếu gì ở đây?

Để có phương pháp cụ thể hơn ServletFileUpload.parseRequest trả về 0 FileItems khi tải lên tập tin lớn

Dưới đây là đoạn mã:

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

Bạn sử dụng thư viện apache chính xác như thế nào? Hiển thị mã cho chúng tôi. –

+0

Bạn nên kiểm tra máy chủ của mình bằng công cụ dòng lệnh thô như "wget" để loại trừ bất kỳ vấn đề nào của máy chủ: kích thước tệp được mã hóa dưới dạng Integer ở đâu đó trong ngăn xếp, giới hạn hệ thống tệp ... –

+0

Các triệu chứng của sự cố của bạn là gì? Chuyển bị kẹt hoặc dừng? Bất kỳ dấu vết ngăn xếp máy chủ nào? Điều gì về hoạt động "trên dây" - nhìn vào nó với wireshark. –

Trả lời

1

tôi chắc chắn có thể mới sai nhưng tôi đã không phát hiện ra rằng ngay cả những 64 bit Trình duyệt xử lý tải lên lớn hơn 2GB. Vấn đề không phải là máy chủ mà là trình duyệt. Bạn sẽ tìm thấy đủ kỳ lạ rằng hầu hết các trình duyệt hiện đại sẽ vui vẻ tải xuống các tệp lớn hơn 2 GB từ máy chủ chuẩn, không cần cấu hình đặc biệt.

+0

Bạn có thể vui lòng cung cấp bất kỳ liên kết nào hỗ trợ câu trả lời của bạn không. Tôi chỉ có thể tìm thấy điều này (http://www.motobit.com/help/ScptUtl/pa33.htm) nhưng tôi không tự tin. – Sunil

+0

Xin chào, cảm ơn bạn đã tham khảo, đã không biết về nó. Nhận xét của tôi dựa trên kinh nghiệm với Apache 2.2, IE và Firefox trong vài năm qua. Thật tuyệt khi nghe về Chrome, tôi đã không thử nghiệm nó trong một thời gian. Flash có thể sẽ không giúp bạn hoặc là, bạn phải gửi dữ liệu trong các phần khá nhỏ so với một tệp lớn và mọi thứ trở nên chậm hơn nhiều. Tất cả các dịch vụ thương mại mà tôi biết là không hỗ trợ lớn hơn 2GB trừ khi bạn sử dụng phần mềm ứng dụng khách của họ. Với thông tin tiêu đề chính xác, tôi không thấy bất kỳ lý do nào khiến Apache không thể xử lý các tệp này. Đó là khuyết tật của trình duyệt. – Mike

+0

đây là [liên kết đến mục lỗi của mozilla] (https://bugzilla.mozilla.org/show_bug.cgi?id = 215450) –

0

Nếu bạn đang mong chờ tải lên tệp của các kích thước đó, tôi sẽ không dựa vào tải lên trình duyệt thẳng. Một applet Java hoặc thậm chí là một tệp Flash (không chắc chắn nếu có thể, không phải là người Flash) sẽ là đề xuất của tôi, vì vậy bạn có thể chia nhỏ các tệp thành các phần. Nếu quá trình tải lên bị gián đoạn, bạn có thể tiếp tục từ nơi nó bị tắt cuối cùng.

+0

Tôi hiểu rằng nó không đáng tin cậy, nhưng có ít yêu cầu về kích thước đó, vì vậy nếu tôi ít nhất có thể xử lý các yêu cầu như vậy, nó sẽ là tuyệt vời. – 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

Nếu bạn đang sử dụng tệp tải lên phổ biến 1.1 hoặc cũ thì bạn không thể tải lên morethan (1.9888) ~ 2GB. Vấn đề ở đây là jar này đang gọi một phương thức có tên là getContentLength có kiểu int, do đó yêu cầu của bạn có thể xử lý kích thước chỉ lên đến Integer.MAX_VALUE. Trong phiên bản mới nhất của tệp tải lên phổ biến như 1,3 này đã được giải quyết. Hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan