【问题标题】:Display PDF in browser with a servlet使用 servlet 在浏览器中显示 PDF
【发布时间】:2013-01-07 19:42:41
【问题描述】:

我想在浏览器中显示一个 PDF 文件。我在 JS 中有 pdf 的路径,我正在调用从 java 中获取 PDF 作为 servlet。这是我目前所拥有的:

JavaScript:

RequestManager.getJSON(Config.server + "getPDF.json?pdfPath=" + this.pathToPdfFile, (function(data){
        $("#" + this.divId).append('<object id="' + this.pdfObjectId + '" data="' + data + '" type="application/pdf" width="600" height="800"></object>');
        ResizeManager.addResizeHandler(this.pdfObjectId, this.divId, -10, -10);
    }).bind(this));

Java:

@RequestMapping("/getPDF")
public void pdfPathToServlet(Model model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
    String pdfPath = request.getParameter("pdfPath");
    if (pdfPath == null || pdfPath.equals(""))
        throw new ServletException("Invalid or non-existent file parameter in UrlServlet servlet.");

    if (pdfPath.indexOf(".pdf") == -1)
        pdfPath += ".pdf";

    File pdf = new File(pdfPath);
    String pdfName = pdfPath.substring(pdfPath.lastIndexOf("/") + 1, pdfPath.length());
    logger.debug(pdfName);
    ServletOutputStream stream = null;
    BufferedInputStream buf = null;
    try 
    {
        stream = response.getOutputStream();
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "inline; filename='" + pdfName + "'");
        FileInputStream input = new FileInputStream(pdf);
        response.setContentLength((int) pdf.length());
        buf = new BufferedInputStream(input);
        int readBytes = 0;
        while ((readBytes = buf.read()) != -1)
            stream.write(readBytes);
    } 
    catch (IOException ioe) 
    {
        throw new ServletException(ioe.getMessage());
    } 
    finally 
    {
        if (stream != null)
            stream.close();
        if (buf != null)
            buf.close();
    }
}

我的问题是,我的浏览器中的 二进制输出 显示为文本。

我不确定我做错了什么。我尝试将标题更改为附件而不是内联,但这显示了同样的事情。我相信我想要内联,因为我希望在浏览器中显示它而不是下载它。

【问题讨论】:

  • 为什么返回application/pdf时你的url以.json结尾?
  • @Michael-O 老实说,我已经习惯了。应用程序的编写方式是整个应用程序在一个 URL 下运行。它从未真正改变过。 .json 通常仅用于防止页面实际重定向到实际上不包含任何内容的另一个 URL。
  • 这根本不是一个 servlet。这是一个 Spring MVC 控制器动作。

标签: java javascript pdf servlets


【解决方案1】:

您的 JavaScript 部分没有意义。您正在获取 PDF 文件作为 ajax 响应,然后尝试将其设置为 &lt;object&gt; 元素的 data 属性。 data 属性必须指向一个真实的 URL,而不是文件内容。相应地修复您的 JS:

$("#" + this.divId).append('<object id="' + this.pdfObjectId + '" data="' + Config.server + "getPDF.json?pdfPath=" + this.pathToPdfFile + '" type="application/pdf" width="600" height="800"></object>');

网络浏览器将负责在给定的 URL 上发送适当的 HTTP 请求,并使用 Adob​​e Acrobat Reader 插件初始化/呈现 &lt;object&gt; 元素 - 如果有的话,我宁愿在 @ 内附上 &lt;a href="pdfURL"&gt;PDF&lt;/a&gt; 987654328@ 以便下载链接至少有一个优雅的降级。


无关具体问题,Java 代码根本不是 servlet 的一部分,而是 Spring MVC 操作。我建议您直接了解您的条款并阅读our Servlets wiki page 以了解它们的真正含义。

【讨论】:

  • 另外,我为糟糕的术语道歉。我通常根本不在这方面工作。最近的就业变化让我暂时陷入了这个困境,而且我的工作期限非常非常紧迫。全速奔向墙壁时试图捡起东西。
  • 您也可以使用 servlet 来完成这项工作。即使已经使用 MVC 框架,也经常这样做。也许这就是造成混乱的地方。
【解决方案2】:
response.setHeader("Content-Disposition", "attachment;filename=" + pdfName);

【讨论】:

    【解决方案3】:
     response.setHeader("Content-Disposition", "inline; filename='" + pdfName + "'");
    

    您不能内嵌显示 PDF。它需要单独在自己的页面(或 Iframe)上。

    【讨论】:

    • 这不是真的。如果您可以在浏览器中使用内联标题值设置初始 url,则 PDF 插件将在浏览器中打开,否则它将打开一个新的 PDF 查看器窗口。
    • 来自 AJAX 调用?我不太确定。
    • 即使attachment 也根本行不通。出于明显的安全原因,JS 没有工具来强制 Save As 对话,其中任意内容保存在某个变量中。整个答案并不适用。请注意,inline 绝对适用于同步请求,前提是浏览器具有相应的插件 (Adobe Reader)。
    猜你喜欢
    • 2017-07-13
    • 2017-05-28
    • 2014-08-03
    • 1970-01-01
    • 2023-02-23
    • 2014-06-18
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多