0

Just to preface this question, the application im working on currently is using JSF2.0, PrimeFaces3.3 and Liferay6.1.1.

The current implementation of the file download works although its running synchronously and successfully downloads in the browser. Below is the commandButton and managedBean method to initiate the download.

CommandButton

<p:commandButton value="#{lbl['lbl.btn.download']}"
    style="float:right;" ajax="false"
    action="#{backingBean.downloadZipFile}" />

ManagedBean

    private void downloadZipFiles() throws IOException, FileNotFoundException{
        String sourceFile = "C:/Users/dev/Documents/test.txt";
        String zipFileName = "TestZip";
        
        PortletResponse portalresponse = (PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
        HttpServletResponse response = PortalUtil.getHttpServletResponse(portalresponse);       
        response.setContentType("application/zip");
        response.setHeader("Content-Encoding", "gzip");
        response.setHeader("Content-Disposition", "attachment; filename="
                + zipFileName + ".zip");
        
        try {

            ZipOutputStream zipOut = new ZipOutputStream(new BufferedOutputStream(
                    response.getOutputStream()));

            File fileToZip = new File(sourceFile);
            FileInputStream fis = new FileInputStream(fileToZip);
            ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
            zipOut.putNextEntry(zipEntry);

            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes)) >= 0) {
                zipOut.write(bytes, 0, length);
            }

            zipOut.closeEntry();
            zipOut.close();
            fis.close();
            response.flushBuffer();
            FacesContext.getCurrentInstance().responseComplete();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

THE PROBLEM

The requirement I was needed to do was adding a BlockUI when the download method is being called. But from what I have read, it appears that file download does not work with Ajax.

Using a commandButton in a jsf Page to download a file

For example, the Loader is shown and hides after the method has finished and when running the code in debug it even went through without an exception occurring. The problem is that the download never starts in the browser. When I set the ajax to false it works normally.

<p:blockUI block=":form" widgetVar="blockWidget">
        <h:graphicImage value="/css/images/ajax-loader.gif"></h:graphicImage>
</p:blockUI>
<p:commandButton value="#{lbl['lbl.btn.download']}"
        style="float:right;" ajax="true" onstart="blockWidget.show();" oncomplete="blockWidget.hide();"
        action="#{backingBean.downloadZipFile}" />

Any recommendations as to how I may approach adding a loader while the zip is being constructed?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Asyraf Dayan
  • 2,792
  • 8
  • 26
  • 39
  • I recommend upgrading to the latest version of PrimeFaces (which is 13, version 3 is pre-historic). Since PrimeFaces 10 you can simply use Ajax downloading. – Jasper de Vries Aug 28 '23 at 10:28
  • @JasperdeVries True that, but the current team advises against upgrading at the moment to not break the application. I'll keep that in mind thanks – Asyraf Dayan Aug 29 '23 at 00:33
  • 1
    Your application is "broken" as it is. There are many security fixes between these versions. It's always best to upgrade. Just make sure you follow the [migration guide](https://primefaces.github.io/primefaces/12_0_0/#/../migrationguide/migrationguide). – Jasper de Vries Aug 29 '23 at 06:58

0 Answers0