John Kim
John Kim

Reputation: 1158

Spring MVC - Downloading PDF using outputstream & HttpServletResponse

I'm trying to write a Controller that downloads a pdf file on the browser. I am using Jasper Reports to generate the pdf file in Java code (fully tested and it works perfectly). Now, I want to get the output stream that is being written by Jasper Reports and download it on the browser. However, when I click the button (which sends a POST to my mapped controller method), no download happens, and no error occurs.

Relevant code :

@RequestMapping("/vm/dormant/pdfReport")
public void exportIdleVMReport(@RequestParam(value = "sdkUrl", required = true) String sdkUrl, 
        @RequestParam(value = "threshold", required = false, defaultValue = "30") int threshold,
        HttpServletResponse response) {

    try {
        //Generated jasperPrint here
        .....

        //OutputStream outputStream = new FileOutputStream(file);
        ServletOutputStream outputStream=response.getOutputStream();
        /* Write content to PDF file */
        JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
        response.addHeader("Content-disposition", "attachment; filename=" + "employee.pdf");
        response.setContentType("application/pdf");
        outputStream.close();
        outputStream.flush();
        System.out.println("File Generated");

    } catch (RemoteException | MalformedURLException e) {
        e.printStackTrace();
    } catch (JRException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

I successfully reach "File Generated" without any errors, I also generate the file using an absolute path and that works just fine. I simply don't get any file download on the browser when I click on the button. Since there is no error either on the server or browser, I don't know what I am doing wrong. Can anyone tell me what is wrong with my code?

EDIT : I don't know if this matters, but I should add that this is an old project in my company. The project uses spring framework dependencies that are version 4.3.0.RELEASE, javax servlet is version 3.0.1.

EDIT 2 : Tested by changing frontend code to reach /vm/dormant/pdfReport directly, and it works! If HttpServletResponse is supposed to send a response back to the URL from where I sent the AJAX, why isn't it working properly?

Upvotes: 0

Views: 3212

Answers (1)

codebrane
codebrane

Reputation: 4620

Looks like the output is being written before the response is set up. I don't know what Jasper does but this might be a more likely order:

response.addHeader("Content-disposition", "attachment; filename=" + "employee.pdf");
response.setContentType("application/pdf");
ServletOutputStream outputStream=response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
outputStream.flush();
outputStream.close();

plus it's good practice to be explicit with the request method:

@RequestMapping("/vm/dormant/pdfReport", method = POST)

If the @RequestParam are being handled slightly differently between GET and POST that may explain why the report generation code doesn't work for POST but does work for GET as per your description.

Upvotes: 1

Related Questions