-1

我不想下载BufferedOutputStreamwhen return java方法。

我的代码:

FacesContext ctx = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse();
response.setHeader("Content-Disposition", "attachment; filename=\"" + "Invoice.zip\";");
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
ZipOutputStream zos = new ZipOutputStream(bos);

for(SalesEInvObject InvoiceObj : this.InvoiceTable){  // MAIN FOR-LOOP STARTS
    if (InvoiceObj.getInvoiceNo() != null) {

        javax.servlet.http.HttpSession httpSession =(javax.servlet.http.HttpSession) ctx.getExternalContext().getSession(false);
        httpSession.setAttribute(BaseHttpServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
                reportOutput.getInternalReportObject());
        byte[] bytes = reportOutput.getReportOutputBytes();
        int length = ((bytes == null) ? 0 : bytes.length);
        response.setContentLength(length*tableSize);
        final ZipEntry ze = new ZipEntry(reportOutputFileName+".pdf");
        zos.putNextEntry(ze);
        zos.write(bytes, 0, bytes.length);
        zos.closeEntry();

    }else {
        return null;
    }
}//LOOP ENDS
zos.close();
ctx.responseComplete();

我的问题是当发票有编号时,它会生成发票并以压缩的 zip 文件下载。但是当它没有号码时,我不想下载 zip。但仍然是 zip 文件下载,但其中没有空文件。

如果没有生成 pdf,我不想下载 zip 文件。

任何帮助...

4

1 回答 1

1

一旦您开始生成 ZIP 并将其写入响应输出流,就没有回头路了。只是打开流会导致响应“提交”......这意味着您不能再更改响应代码或标头。

基本上,您需要在开始生成响应之前检查是否有任何发票。那么它应该只是重组现有代码的问题。

就像是 .....

boolean hasInvoices = false;
for (SalesEInvObject invoiceObj : this.InvoiceTable) {
    if (invoiceObj.getInvoiceNo() != null) {
        hasInvoices = true;
        break;
    }
}

FacesContext ctx = FacesContext.getCurrentInstance();
HttpServletResponse response = 
    (HttpServletResponse) ctx.getExternalContext().getResponse();
if (hasInvoices) {
    response.setHeader("Content-Disposition", 
                       "attachment; filename=\"" + "Invoice.zip\";");
    BufferedOutputStream bos = 
        new BufferedOutputStream(response.getOutputStream());
    ZipOutputStream zos = new ZipOutputStream(bos);
    
    for (SalesEInvObject invoiceObj : this.InvoiceTable) {  
        if (invoiceObj.getInvoiceNo() != null) {
            javax.servlet.http.HttpSession httpSession = 
                (javax.servlet.http.HttpSession) ctx.getExternalContext()
                                                    .getSession(false);
            httpSession.setAttribute(
                    BaseHttpServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
                    reportOutput.getInternalReportObject());
            byte[] bytes = reportOutput.getReportOutputBytes();
            int length = ((bytes == null) ? 0 : bytes.length);
            response.setContentLength(length * tableSize);
            final ZipEntry ze = new ZipEntry(reportOutputFileName + ".pdf");
            zos.putNextEntry(ze);
            zos.write(bytes, 0, bytes.length);
            zos.closeEntry();
        }
    }
    zos.close();
} else {
    // do you want to set a response code or something?
}
ctx.responseComplete();

我已经修复了一些不好的风格。看看你能不能发现变化...

还有一个我没有解决的问题:即在这段代码中打开的各种资源应该使用try with resources来管理。但是,这可能不是必需的,因为看起来资源都基于请求输出流。这将由 servlet 基础结构自动关闭。

于 2021-06-06T14:34:07.423 回答