2013-08-20 47 views
3

我有一个按钮,它打开一个带有生成的pdf文件的新选项卡。 但是,当我点击按钮后,我想导航到另一个页面。在新标签页/窗口中打开/下载文件时刷新/浏览当前页面

这意味着,点击按钮后,我想用pdf打开一个新选项卡并导航到最初选项卡上的另一页。我正在使用primefaces p:commandButton并尝试onclick="window.location.href='www.google.de'",但它不起作用。但是onclick="window.lalert('www.google.de')"确实有效。

这是我的代码:

<h:form id="transForm" target="_blank"> 
<p:commandButton value="Zertifikat erstellen" ajax="false" 
           label="Speichert die Anmeldung und erstellt ein Zertifikat im PDF-Format" 
           action="#{transportErfassen.generatePDFZertifikat()}"/> 

</h:form> 

generatePDFZertifikat()确实创建PDF文件与下面的代码,我觉得这里的问题:

FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 

    externalContext.setResponseContentType("application/pdf"); 
    externalContext.setResponseHeader("Expires", "0"); 
    externalContext.setResponseHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0"); 
    externalContext.setResponseHeader("Pragma", "public"); 
    externalContext.setResponseHeader("Content-disposition", "inline; filename=\"" + fileName +"\""); 
    externalContext.setResponseContentLength(out.length); 
    externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", new HashMap<String, Object>()); 

    //setze explizit auf OK 
    externalContext.setResponseStatus(200);  

    OutputStream os = externalContext.getResponseOutputStream(); 
    os.write(out, 0, out.length); 
    os.flush(); 

    facesContext.responseComplete();  
    facesContext.renderResponse();  

回答

3

你基本上要发送2级响应回到1请求。这不会在HTTP中工作。如果你想发回2个回复,你必须让客户以某种方式触发2个请求。您已经在寻找解决方案的正确方向,只需很少的JavaScript帮助就可以在单个事件上触发多个请求(单击)。然而,您在onclick中的尝试无效,在提交表单之前单击提交按钮,更改window.location,完全中止按钮的原始操作,提交表单。

最好的办法就是直接导航到结果页面而这又调用JavaScript的window.open()在页面加载,指着你想打开PDF文件的URL。这是不可能发送一些HTML/JS代码连同PDF文件指示导航(因为这显然会破坏PDF文件)。这也意味着,您无法直接将PDF返回到表单提交请求。代码必须重新设计,以便可以通过后续的GET请求来检索PDF。最好的方法是使用一个简单的servlet。您可以将生成的PDF临时存储在磁盘或会话中并与唯一密钥关联,并将该唯一密钥作为请求路径信息或参数传递给window.open() URL中的servlet。

这里的一个开球例如:

初始形式:

<h:form> 
    ... 
    <p:commandButton ... action="#{bean.submit}" /> 
</h:form> 

豆:

public String submit() { 
    File file = File.createTempFile("zertifikat", ".pdf", "/path/to/pdfs"); 
    this.filename = file.getName(); 

    // Write content to it. 

    return "targetview"; 
} 

目标视图:

<h:outputScript rendered="#{not empty bean.filename}"> 
    window.open('#{request.contextPath}/pdfservlet/#{bean.filename}'); 
</h:outputScript> 

PDF的servlet(nullchecks等为简洁起见省略; Java 7中承担了Files#copy()):

@WebServlet("/pdfservlet/*") 
public class PdfServlet extends HttpServlet { 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     File file = new File("/path/to/pdfs", request.getPathInfo().substring(1)); 
     response.setHeader("Content-Type", "application/pdf"); 
     response.setHeader("Content-Length", String.valueOf(file.length())); 
     response.setHeader("Content-Disposition", "inline; filename=\"zertifikat.pdf\""); 
     Files.copy(file.toPath(), response.getOutputStream()); 
    } 

} 
+0

感谢您的回复,我真的很感激。 <3 – leostiw

+0

不客气:) – BalusC

1

正如BalusC说,Refresh/navigate current pageopening downloading file是两个不同的反应,必须有两个resquests。我遇到了类似的问题。我用jsf ajax成功解决了它。

这里是我的代码部分:

XHTML:

<h:commandButton id="download-button" class="download-button" 
    value="download"> 
<f:ajax event="click" execute="@form" render=":msg-area" 
    listener="#{myController.checkForDownload}" onevent="checkCallBack" /> 
</h:commandButton> 
<h:commandButton id="download-button2" class="download-button2" 
    value="download" style="display: none;" 
    action="#{myController.download}"> 
</h:commandButton> 

的Javascript:

function checkCallBack(data) { 
    var ajaxStatus = data.status; 
    switch (ajaxStatus) { 
    case "begin": 
     break; 
    case "complete": 
     break; 
    case "success": 
     document.getElementById('download-form:download-button2').click(); 
     break; 
    } 
} 

download-button呈现页面上的信息区和download-button2触发下载方法。他们是两个不同的要求。当第一个请求完成时,第二个请求将被触发。

相关问题