java - Spring MVC - 使用输出流和 HttpServletResponse 下载 PDF

标签 java rest spring-mvc servlets jasper-reports

我正在尝试编写一个在浏览器上下载 pdf 文件的 Controller 。我正在使用 Jasper Reports 在 Java 代码中生成 pdf 文件(经过充分测试,效果完美)。现在,我想获取 Jasper Reports 正在编写的输出流并将其下载到浏览器上。但是,当我单击该按钮(将 POST 发送到我的映射 Controller 方法)时,不会发生下载,也不会发生错误。

相关代码:

@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();
    }
}

我成功到达“文件生成”,没有任何错误,我还使用绝对路径生成文件,效果很好。当我单击按钮时,我根本没有在浏览器上下载任何文件。由于服务器或浏览器上都没有错误,我不知道我做错了什么。谁能告诉我我的代码有什么问题吗?

编辑: 我不知道这是否重要,但我应该补充一点,这是我公司的一个老项目。该项目使用的spring框架依赖版本是4.3.0.RELEASE,javax servlet是版本3.0.1。

编辑2:通过更改前端代码以直接到达/vm/dormant/pdfReport进行测试,并且它有效!如果 HttpServletResponse 应该将响应发送回我发送 AJAX 的 URL,为什么它不能正常工作?

最佳答案

看起来输出是在设置响应之前写入的。我不知道 Jasper 做了什么,但这可能是一个更可能的顺序:

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

另外,明确请求方法是一个很好的做法:

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

如果 @RequestParamGETPOST 之间的处理方式略有不同,这可能解释了为什么报告生成代码不起作用POST 但根据您的描述,确实适用于 GET

关于java - Spring MVC - 使用输出流和 HttpServletResponse 下载 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58537465/

相关文章:

java - 演示 ReadWriteLock 用法的示例

java - 使用 Jersey 上传文件不起作用

android - 移动设备上的 Worldpay 通知

java - Mockito - 模拟服务时抛出 nullpointerException

spring-mvc - 仅发送到某些连接Spring Websockets

java - 配置 Java GUI 应用程序的响应能力

java - 使用哪个 List 实现?

Java 正则表达式 : Count words/phrases/wildcards in HTML document

c# - RestSharp 响应返回空

java - hybris中jsp中project.properties文件的读取