java - 如何使 pdf 显示为下载选项而不是在浏览器上呈现?

标签 java http rest jasper-reports download

我在我的项目中使用 Jasper Reports 来生成多种格式的报告。尽管所有代码示例都运行良好,但我遇到了一个概念问题。

我编写了这段简单的代码,它在浏览器中生成 PDF 作为下载选项:

    @GET
    @Path("/basicdbreport")
    @Produces("application/pdf")
    public Response basicDbReport(@Context ServletContext context,
            @Context HttpServletResponse response) throws JRException,
            IOException {
        Connection connection = null;
        byte[] reportBytes = null;
        String reportName = "firstsqlexample";

        File file = new File(path + reportName + JASPER_EXTENSION);

        // check if compiled report exists
        if (!file.exists()) {
            compileReport(context.getRealPath(path + reportName + JRXML_EXTENSTION));
        }

        // input stream for filling the compiled report
        InputStream compiledReportStream = context.getResourceAsStream(path
                + reportName + JASPER_EXTENSION);

        try {
            connection = dataSource.getConnection();
            reportBytes = JasperRunManager.runReportToPdf(compiledReportStream,
                    new HashMap<String, Object>(), connection);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (reportBytes != null) {
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(reportBytes);
        }

        ResponseBuilder restResponse = Response.ok();
        restResponse.header("Content-Disposition",
                "attachment; filename=firstSQLReport.pdf");
        return restResponse.build();
    }

代码运行良好,我在浏览器中收到下载提示。然而,当我深入研究 Jasper API 时,我发现了一个方法 runReportToPdfStream()为我处理输出流的方法。

新代码如下所示:

    @GET
    @Path("/basicdbreport")
    @Produces("application/pdf")
    public Response basicDbReport(@Context ServletContext context,
            @Context HttpServletResponse response) throws JRException,
            IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        Connection connection = null;
        String reportName = "firstsqlexample";

        File file = new File(path + reportName + JASPER_EXTENSION);

        // check if compiled report exists
        if (!file.exists()) {
            compileReport(context.getRealPath(path + reportName + JRXML_EXTENSTION));
        }

        // input steam to fill complied report
        InputStream compiledReportStream = context.getResourceAsStream(path
                + reportName + JASPER_EXTENSION);

        try {
            connection = dataSource.getConnection();
            JasperRunManager.runReportToPdfStream(compiledReportStream, outputStream, new HashMap<String, Object>(), connection);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        ResponseBuilder restResponse = Response.ok();
        restResponse.header("Content-Disposition",
                "attachment; filename=firstSQLReport.pdf");
        return restResponse.build();
    }

代码运行良好,但我没有收到任何下载提示,而是在浏览器上呈现 pdf。响应 header 如下(在浏览器上):

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Date: Wed, 21 Aug 2013 05:51:42 GMT

代码现在无法提供下载提示的原因是什么?我不是 HTTP 高手,但我猜是这样的:

restResponse.header("Content-Disposition",
                    "attachment; filename=firstSQLReport.pdf");

负责下载选项。尽管我确实将其包含在代码中,但它不在响应中。请指教。

最佳答案

是的,你是对的,Content-Disposition 是您需要设置的响应 header ,以触发客户端浏览器上的下载操作。

我认为您需要先设置响应 header ,然后再写入响应输出流。

关于java - 如何使 pdf 显示为下载选项而不是在浏览器上呈现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18349839/

相关文章:

java - 将MatOfInt转换为MatofPoint

java - 我无法导入 org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer

python - 如何在 aiohttp 服务器响应正文中提供客户端请求 header 和服务器响应 header ?

java - 在基于 REST 的应用程序上是否有与 Python 的请求模块等效的 Java

java - Sybase 中的 JDBC 事务控制

Java 同步方法和 block

web-services - 报告 RESTful Web 服务内部服务错误 500 的最佳实践?

java - 使用 Java 托管 HTTP 端点

python - 为 django-rest-framework + Angular-route + 静态文件设置 urls.py 的正确方法是什么?

java - CitrusFramework - 无法通过 cucumber java运行