首页 > 解决方案 > 从 Servlet 返回时无法下载 JSF PDF

问题描述

我有一个表单,一旦完成就会打开一个新选项卡并调用我的 bean 方法 annonceReturn()。

此方法发回一个 pdf 文件。问题是当我用 _blank 打开一个新选项卡时,URL 以 .xhtml 结尾。甚至文件名也显示为在我的示例“list.xhtml”(URL 的最后一部分)中。问题是我无法下载此文件,因为它不被视为 pdf 文件。

这是我的 xhtml 文件:

<h:form id="form">    
    <p:commandButton id="envoiRetour" onclick="this.form.target = '_blank';"
        actionListener="#{returnCtrl.announceReturn()}" 
        value="Open PDF in new tab"
        ajax="false" />
</h:form>

这是 returnCtrl.annonceReturn() 方法:

public void announceReturn() throws MalformedURLException, FileNotFoundException, DocumentException, BadElementException, IOException, InterruptedException {
    String referenceAnnouncement = "C:/Users/path_to_my_pdf_file.pdf";
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
    BufferedInputStream input = null;
    BufferedOutputStream output = null;

    try {
        input = new BufferedInputStream(new FileInputStream(referenceAnnouncement), 10240);
        response.reset();
        response.setHeader("Content-type", "application/pdf"); 
        response.setContentLength((int)new File(referenceAnnouncement).length());
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setHeader("Content-disposition", "inline; filename=" + "file.pdf");
        response.setHeader("pragma", "public");

        output = new BufferedOutputStream(response.getOutputStream(), 10240);
        byte[] buffer = new byte[10240];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
        output.flush();
    } finally {
        output.close();
        input.close();
    }
}

如何在新选项卡中打开此 PDF 并能够下载?

当我尝试下载它时,它说存在网络错误(并尝试将其保存为 xhtml 文件)。

编辑:这是帮助我的问题:如何在新选项卡中打开 PDF 文件

编辑 2:问题不在于 PDF 不显示。问题是它显示在新选项卡中,但是当我尝试下载它时,资源管理器希望将其保存为 XHTML 文件。

编辑3:正如提到的here - >在新选项卡中打开PDF,保存文件给出错误的文件名 ,如果处置不是“附件”,似乎文件名被忽略......所以我想我需要考虑另一种方法来做到这一点.

谢谢你的时间。

标签: pdfinternet-explorerjsfdownload

解决方案


这是我的代码,希望对您有所帮助。

FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();

File temp = File("./path/abc.pdf");
temp.deleteOnExit();
ec.responseReset(); 
ec.setResponseContentType("application/pdf"); 
ec.setResponseContentLength((int)temp.length()); 
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + temp.getName() + "\""); //inline; 

OutputStream output = ec.getResponseOutputStream();

Files.copy(temp.toPath(), output);
fc.responseComplete();

推荐阅读