Java servlet:文件下载损坏的问题

时间:2010-10-04 13:02:29

标签: java servlets download corruption

我使用三个servlet来提供下载文件:

  • ByteArrayDownloadServlet:用于小文件,例如数据库中的报告或文件
  • FileDownloadServlet:用于小到大文件
  • MultipleFileDownloadServlet:使用所请求的文件创建一个zip并将其流式传输

它们基于以下实现: link text

我收到了一些有关下载损坏的投诉。问题是我无法在错误中模拟或找到模式:

  • 有时会使用大文件
  • 有时当用户请求下载多个文件和zip文件并且是动态创建时
  • 有时使用较小的文件,但许多用户同时请求

在上面提到的帖子中,有人报告类似的问题,但没有解决方案。我也从这里读了很多帖子,这越接近我: link text

有没有人遇到类似的问题或者有一些有效的示例代码?

谢谢, 菲利普

@Override
@SuppressWarnings("unchecked")    
protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
{
    HttpSession session = request.getSession();
    List<File> selectedFileList = (List<File>) session.getAttribute("selectedFileList");

    if(selectedFileList == null)
    {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, "Lista de arquivos não informada");
        return;
    }

    response.reset();
    response.setContentType("application/zip");        

    response.setHeader("Content-Disposition", "attachment; filename=\""
        + "atualizacoes_"
        + new Date().getTime() + ".zip" + "\"");

    ZipOutputStream output = null;

    try
    {
        output = new ZipOutputStream(response.getOutputStream());

        for(File file : selectedFileList)
        {
            InputStream input = new FileInputStream(file);
            output.putNextEntry(new ZipEntry(file.getName()));                

            byte[] buffer = new byte[DownloadHandler.DEFAULT_BUFFER_SIZE];
            int length;
            while((length = input.read(buffer)) > 0)
            {
                output.write(buffer, 0, length);
            }

            output.closeEntry();
            input.close();
        }            

     output.finish();
     output.flush();
     output.close();
  }
  catch(Exception e) 
  {
      if(!(e instanceof ClientAbortException))
      {
          new ExceptionMail(getClass().getSimpleName(), e);
      }
    }
  finally
  {            
        session.removeAttribute("selectedFileList");        
  }

3 个答案:

答案 0 :(得分:2)

从servlet下载的随机损坏的最常见原因是servlet不是线程安全的和/或它正在读取字节作为字符。在同一会话或servletcontext中的请求之间共享请求或基于会话的数据也可能是导致此问题的原因。

答案 1 :(得分:0)

您不应关闭输出流,因为它由servlet容器管理。 我不确定冲洗。

答案 2 :(得分:0)

您的代码在以下行中有严重的流程。

int length;
        while((length = input.read(buffer)) > 0)
        {
            output.write(buffer, 0, length);
        }

你的'输入'是FileInputStream吗?如何确保FileInputStream在整个迭代过程中始终具有超过0个字节的可用空间?相反,它必须写成如下。

int length;
        while((length = input.read(buffer)) != -1)
        {
            output.write(buffer, 0, length);
        }