使用Servlet在浏览器中显示PDF

3

我可以帮你翻译成中文。这篇文章是关于IT技术的,主要内容是如何在浏览器上显示PDF文件。我有一个指向PDF的路径,并且通过调用Java中的servlet来获取PDF内容。以下是我的JavaScript代码:

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格式,为什么你的网址以.json结尾? - Michael-O
@Michael-O老实说,我之前是出于习惯才这样做的。应用程序的编写方式是在一个URL下运行整个应用程序。它从未真正改变过。.json通常用于防止页面重定向到实际上没有任何内容的另一个URL。 - user856354
1
那根本不是一个servlet,那是Spring MVC控制器的动作。 - BalusC
3个回答

5

你的JavaScript部分没有意义。你正在作为ajax响应获取PDF文件,然后尝试将其设置为<object>元素的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上,web浏览器会负责发送适当的HTTP请求,并使用Adobe Acrobat Reader插件(如果有)初始化/渲染<object>元素。我建议将<a href="pdfURL">PDF</a>嵌套在<object>中,这样至少可以优雅地降级到下载链接。


与具体问题无关,这段Java代码根本不是一个servlet,而是Spring MVC操作。我建议您搞清楚术语并阅读我们的Servlets wiki页面,了解它们的真正含义。


1
另外,我对术语使用不当深感抱歉。我通常根本不从事这方面的工作。最近的就业变化暂时将我投入到这个领域中,并且我正在极其紧迫的期限内工作。试图在全速冲向墙壁时学习和适应。 - user856354
您也可以使用Servlet完成此任务。即使已经使用了MVC框架,通常也会这样做。也许这就是混淆的原因所在。 - BalusC

0
response.setHeader("Content-Disposition", "attachment;filename=" + pdfName);

-1
 response.setHeader("Content-Disposition", "inline; filename='" + pdfName + "'");

您无法将 PDF 内联显示。它需要独立于自己的页面上(或 iframe 中)。

3
不正确。如果您在浏览器中使用内联标头值调用初始URL,则PDF插件将在浏览器中打开,否则它将打开一个新的PDF查看器窗口。 - Michael-O
从一个AJAX调用?我不太确定。 - Diodeus - James MacFarlane
即使使用“attachment”,也无法起作用。出于明显的安全原因,JS没有强制使用任意内容保留在某个变量中的“另存为”对话框的功能。整个答案都不适用。请注意,“inline”绝对适用于同步请求,前提是浏览器具有相应的插件(Adobe Reader)。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接