我目前有2个命令按钮和一个列表框。根据列表框选择,生成的结果可以显示在可下载文件中,也可以呈现为HTML表格。 getFile()
代码基于BalusC's PDF Handling tutorial,而getTable()
代码resultTable
。
<h:form>
<fieldset>
<h:selectManyListbox id="listbox" value="#{form.items}">
<f:selectItems value="#{form.allItems}">
</h:selectManyListbox>
</fieldset>
<h:commandButton value="Get File" action="#{form.getFile}">
<h:commandButton value="Get Table" action="#{form.getTable}">
<f:ajax render="result_table" execute="listbox" />
</h:commandButton>
<h:panelGrid id="result_table">
<table>
<thead></thead>
<tbody>
<ui:repeat var="table" value="#{form.resultTable}">
</ui:repeat>
</tbody>
</table>
</h:panelGrid>
到目前为止,两个按钮都正常工作。但是,我想将两个动作组合成一个按钮。当我用一个触发两个动作的按钮测试它时,没有任何反应(没有文件保存为对话框或表格渲染)。这是因为一个动作是ajax还是因为另一个动作是以facesContext.responseComplete();
完成的?
<h:commandButton value="Get Both" action="#{form.getBoth}">
<f:ajax render="result_table" execute="listbox" />
</h:commandButton>
getBoth() {
getTable();
getFile();
}
此外,我想要一个复选框,如果选中它,则保存为弹出对话框并呈现表格。如果未选中,则仅渲染表。
答案 0 :(得分:1)
不幸的是,HTTP无法实现这一点。每个请求只能发送一个响应。您不能将包含PDF文件和ajax响应的响应合并到一个响应中。由于这是一个HTTP限制,JSF不能为您做任何事情。此外,由于安全限制,JavaScript无法强制浏览器弹出另存为对话框,也无法访问本地磁盘文件系统,因此无法使用Ajax下载文件。
解决方法是在单个按钮单击时触发两个 HTTP请求,其中第二个请求返回Content-Disposition: attachment
,以便其他请求的响应保持不变。您可以通过在命令按钮中添加onclick
来实现此目的。
<h:commandButton onclick="window.location='/context/pdfservlet/filename.pdf'">
并创建一个大致类似this FileServlet example的PDF servlet。如您所见,由此无法调用JSF操作。您必须将PDF下载方法重构为以HttpServlet
方法完成工作的doGet()
类。对于JSF托管bean和servlet之间的任何必要通信,您可以使用会话范围或通过请求路径或参数传递所需信息(只是PDF文件标识符?)。
答案 1 :(得分:0)
我传递了一个类似的案例,在我的情况下,我使用ajax richfaces标签lib和环绕命令按钮与ajax表单标签解决。
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">
<a4j:form id="formDownloads">
<rich:panel>
<h:commandButton value="Exportar para PDF" status= "block" ... />
</rich:panel>
</a4j:form>