Java SpringMVC-使用outputstream和HttpServletResponse下载PDF

Java SpringMVC-使用outputstream和HttpServletResponse下载PDF,java,rest,spring-mvc,servlets,jasper-reports,Java,Rest,Spring Mvc,Servlets,Jasper Reports,我正在尝试编写一个在浏览器上下载pdf文件的控制器。我正在使用Jasper Reports以经过充分测试的Java代码生成pdf文件,该文件运行良好。现在,我想获得Jasper Reports正在编写的输出流,并将其下载到浏览器上。但是,当我单击向映射的控制器方法发送POST的按钮时,不会发生下载,也不会发生错误 相关代码: @RequestMapping("/vm/dormant/pdfReport") public void exportIdleVMReport(@RequestParam(

我正在尝试编写一个在浏览器上下载pdf文件的控制器。我正在使用Jasper Reports以经过充分测试的Java代码生成pdf文件,该文件运行良好。现在,我想获得Jasper Reports正在编写的输出流,并将其下载到浏览器上。但是,当我单击向映射的控制器方法发送POST的按钮时,不会发生下载,也不会发生错误

相关代码:

@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:通过将前端代码直接更改为reach/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();
另外,使用request方法显式是一种很好的做法:

@RequestMapping/vm/dormant/pdfReport,方法=POST


如果GET和POST之间对@RequestParam的处理略有不同,这可能解释了为什么报告生成代码不适用于POST,但根据您的描述,它适用于GET。

尝试了此方法。还是不行。在OP.frontend代码中添加了其他信息,以便直接访问/vm/dormant/pdfReport这意味着什么?为什么不直接发送到那里?@codebrane这意味着不用ajax发布到/vm/dormant/pdfReport,我直接用参数构建URL字符串,并让按钮打开指向该URL的新窗口。现在,当我单击按钮时,页面会加载一段时间,然后下载文件并自动关闭选项卡。除了前端代码,我什么都没改。为什么当我发送AJAX时servlet响应不起作用,但是如果我直接访问URL,它就可以正常工作?这听起来像是在用按钮GET,而用AJAX调用POST。可能有细微的差别。我已经更新了答案,明确使用POST作为方法,看看这是否有助于Ajax调用。目前,该方法将同时处理这两个问题,但最好明确说明该方法