h:commandLink没有在不使用f:ajax的情况下触发文件下载操作

时间:2012-04-10 12:39:34

标签: java jsf jsf-2 pdf-generation download

我有一个h:datatable,其中包含一个链接列,该列将调用辅助bean并“应该”返回生成的PDF文档。

该列如下所示:

<h:form>
    ...
    <h:datatable>
        ...
        <h:column >
            <h:commandLink action="#{bean.downloadPDF}" target="_blank" >
                <f:param name="value1" value="#{bean.val1}"/>
                <f:param name="value2" value="#{bean.val2}"/>
                <f:param name="value3" value="#{bean.val3}"/>
                <h:graphicImage name="certificate.jpg" library="images"/>
            </h:commandLink>
        </h:column>
        ...
    </h:datatable>
...
</h:form>  

我的页面上没有javascript错误(根据chrome和firebug)。支持bean看起来像这样:

public void downloadPDF() {
...
File outputPDF = new File(outputFileName);

//Get ready to return pdf to user
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
    // Open file.
    input = new BufferedInputStream(new FileInputStream(outputPDF), 10240);

    //Return PDF to user
    // Init servlet response.
    response.reset();
    response.setHeader("Content-Type", "application/pdf");
    response.setHeader("Content-Length", String.valueOf(outputPDF.length()));
    response.setHeader("Content-Disposition", "inline; filename=\"" + pdfName + "\"");
    output = new BufferedOutputStream(response.getOutputStream(), 10240);

    // Write file contents to response.
    byte[] buffer = new byte[10240];
    int length;
    while ((length = input.read(buffer)) > 0) {
        output.write(buffer, 0, length);
    }

    // Finalize task.
    output.flush();
} catch(IOException e) {
    e.printStackTrace();
} finally {
    output.close();
    input.close();
}
facesContext.responseComplete();
}

现在,我知道我的PDF生成有效,因为我可以创建自定义PDF并将其保存在驱动器上。

然后,如果我将<f:ajax/>添加到h:commandLink,则调用该方法。没有它,它会重新加载当前页面,而不会调用操作方法。

我尝试了一些不同的事情......有或没有任何f:param。将String返回值添加到downloadPDF()函数。 编辑:取消target="_blank"参数。使用actionListener代替action。使用action时,不会调用bean方法,但我在h:messagesConversion Error setting value '' for 'null Converter'.中收到此错误消息。

无法让它调用该函数。我希望得到的是,当点击downloadPDF链接时,它会打开一个新窗口并下载PDF。

非常感谢任何帮助。

编辑2 /解决方案(临时)

我已设法使用属性immediate="true"来实现此功能。仍然没有找到给我Conversion Error的确切字段,但假设是一个不需要为此特定函数提交的表单中的字段。

1 个答案:

答案 0 :(得分:1)

与问题相关的逻辑很好。问题在于表单中的其他项目保持为空。与编辑2 一样,添加immediate="true"使得我单独需要的字段被发送到servlet。

经验教训

在JSF中提交表单的一部分时,请确保仅提交您需要的字段。特别是在大型表格中,并将ajax与表格的子部分集成在一起。