代码之家  ›  专栏  ›  技术社区  ›  NeilInglis

将文件数据作为Bzip2写入servlet响应的输出

  •  1
  • NeilInglis  · 技术社区  · 16 年前

    我正试图让Tomcat将servlet内容写成bzip2文件(这可能是一个愚蠢的要求,但对于一些集成工作来说显然是必要的)。我使用的是Spring框架,所以这是在一个AbstractController中。

    我用的是来自 http://www.kohsuke.org/bzip2/

    我可以很好地得到bzipped的内容,但是当文件被写出来时,它似乎包含了一堆元数据,并且无法识别为bzip2文件。

    // get the contents of my file as a byte array
    byte[] fileData =  file.getStoredFile();
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
    //create a bzip2 output stream to the byte output and write the file data to it             
    CBZip2OutputStream bzip = null;
    try {
         bzip = new CBZip2OutputStream(baos);
         bzip.write(fileData, 0, fileData.length);
         bzip.close();  
    } catch (IOException ex) {
         ex.printStackTrace();
    }
    byte[] bzippedOutput = baos.toByteArray();
    System.out.println("bzipcompress_output:\t" + bzippedOutput.length);
    
    //now write the byte output to the servlet output
    //setting content disposition means the file is downloaded rather than displayed
    int outputLength = bzippedOutput.length;
    String fileName = file.getFileIdentifier();
    response.setBufferSize(outputLength);
    response.setContentLength(outputLength);
    response.setContentType("application/x-bzip2");
    response.setHeader("Content-Disposition",
                                           "attachment; filename="+fileName+";)");
    

    这是从Spring abstractcontroller中的以下方法调用的

    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)  throws Exception
    

    我尝试过几种不同的方法,包括直接写入ServletOutput,但我很困惑,在网上找不到任何/许多例子。

    任何人的任何建议谁遇到过这将不胜感激。可供选择的库/方法很好,但不幸的是,它必须是bzip2'd。

    2 回复  |  直到 16 年前
        1
  •  3
  •   BalusC    16 年前

    张贴的方法确实很奇怪。我已经重写了,所以它更有意义。试试看。

    String fileName = file.getFileIdentifier();
    byte[] fileData = file.getStoredFile(); // BTW: Any chance to get this as InputStream? This is namely memory hogging.
    
    response.setContentType("application/x-bzip2");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    
    OutputStream output = null;
    
    try {
         output = new CBZip2OutputStream(response.getOutputStream());
         output.write(fileData);
    } finally {
         output.close();
    }
    

    你看,只要用 CBZip2OutputStream 然后写下 byte[]

    你可能碰巧看到 IllegalStateException: Response already committed 远离 null 够了。

        2
  •  2
  •   Tim R    16 年前

    CompressorStreamFactory 从…起 commons-compress 简单一点。它是你已经在使用的Ant版本的继承者,结果与BalusC的例子有两行不同。

    或多或少是图书馆偏好的问题。

    OutputStream out = null;
    try {
        out = new CompressorStreamFactory().createCompressorOutputStream("bzip2", response.getOutputStream());
        IOUtils.copy(new FileInputStream(input), out); // assuming you have access to a File.
    } finally {
        out.close();
    }