0

複数の形式でレポートを作成するために、プロジェクトで 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 がブラウザーでレンダリングされます。応答ヘッダーは次のとおりです (ブラウザー上)。

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");

ダウンロードオプションを担当します。コードに含めましたが、応答のどこにもありません。ご意見をお聞かせください。

4

1 に答える 1

2

はい、そのとおりContent-Dispositionです。これは、クライアント ブラウザーでダウンロード アクションをトリガーするために設定する必要がある応答ヘッダーです。

応答出力ストリームに書き込む前に、最初に応答ヘッダーを設定する必要があると思います。

于 2013-08-21T06:14:27.457 に答える