无法从JSF页面下载zip文件



我试图将多个PDF文件下载为一个zip文件,然后更新JSF页面上的详细信息—有效地显示我正在处理这些文件。我在后台使用两个请求实现了这一点- 1)更新DB详细信息并刷新屏幕2)下载zip文件。

这在单工作站windows环境中工作得很好,但是当我在Linux环境中部署它时,在负载平衡器后面,我在尝试下载zip时得到一个空白页面。我已经编写了SOP统计数据来打印通过JSF BB发送到ServletOutputStream的文件的大小,并且我发现正在打印正确的文件大小。但是不知何故,我不断丢失zip和更新的JSF。这种情况在Windows中也会随机发生,这让我很担心。请提供宝贵的建议,帮助我解决这个问题。

你可以考虑以下几点:我使用的是Richfaces 3.3.3 Final, IE 8浏览器,响应传输编码类型是分块的。

= = = =BB方法如下所示:

String checkoutDoc = service.checkout(docId,true,contract, error);
FacesContext ctx = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse();
File tempPdf = new File(checkoutDoc);URI tempURI = tempPdf.toURI();
URL pdfURL = tempURI.toURL();ServletOutputStream outstream =response.getOutputStream();
try 
{
 URLConnection urlConn = pdfURL.openConnection();
 response.setContentType("application/zip");
 response.setHeader("Transfer-Encoding", "chunked");
 response.addHeader("Content-disposition", "attachment;filename="+docId.toString()+".zip" );
 BufferedInputStream bufInStrm = new BufferedInputStream (urlConn.getInputStream());
 int readBytes = 0;
 int bufferSize = 8192;
 byte[] buffer = new byte[bufferSize];
 while ((readBytes = bufInStrm.read(buffer)) != -1){
if (readBytes == bufferSize) {
    outstream.write(buffer);
 }else{
    outstream.write(buffer, 0, readBytes);
    }
    outstream.flush();
    response.flushBuffer();
    }
    bufInStrm.close();
    }finally{
     outstream.close();
    }
    FacesContext.getCurrentInstance().responseComplete();
}

我使用Firefox Http监视器捕获的响应头如下所示。

(Request-Line)  POST /XXX/application/pages/xxx.xhtml HTTP/1.1
Host    xxx.xxx.com
User-Agent  Mozilla/5.0 (Windows NT 5.1; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection  keep-alive
Referer http://xxx.com/xxx/application/pages/xxx.xhtml
Cookie  JSESSIONID=E27C156AA37E5984073FAB847E4958D2.XXXX;  fontSize=null; pageWidth=fullWidth
Content-Type    multipart/form-data; boundary=---------------------------288695814700
Content-Length  1442

你应该设置自己的Transfer-Encoding: chunked头,如果你是实际上不写用块编码自己使用例如ChunkedOutputStream的文件。当响应缓冲区已满且响应内容长度未知时,Servlet API将自动执行此操作。但是,如果您自己设置了这个头,而没有实际地以分块编码写出正文,则行为是完全未指定的,并且依赖于所使用的servlet容器。

删除头文件,让Servlet API完成它的工作。为了提高性能(以便Servlet API在响应缓冲区已满时不会切换到分块编码),也可以设置响应内容长度头。

话虽如此,你的流式传输方法有点笨拙。不需要将File按摩到URL, for回路中的if-else也不需要。我可以给您以下建议吗?

// ...
File tempPdf = new File(checkoutDoc);
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.setResponseContentType("application/zip");
externalContext.setResponseHeader("Content-Disposition", "attachment;filename="" + docId + ".zip"");
externalContext.setResponseHeader("Content-Length", String.valueOf(tempPdf.length()));
Files.copy(tempPdf.toPath(), externalContext.getResponseOutputStream());
FacesContext.getCurrentInstance().responseComplete();

参见:

    如何从JSF支持bean提供文件下载?

相关内容

  • 没有找到相关文章

最新更新