JavaH:commandButton多个操作:下载文件并呈现ajax表
我目前有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();
}
此外,我希望有一个复选框,如果选中,则会弹出“另存为”对话框并呈现表格。如果未选中,则仅呈现表
# 1 楼答案
不幸的是,这在HTTP中是不可能的。每个请求只能发送一个响应。不能将包含PDF文件的响应和ajax响应合并为一个响应。由于这是一个HTTP限制,JSF不能为您做任何事情。此外,使用Ajax下载文件是完全不可能的,因为JavaScript无法强制浏览器弹出另存为对话框,也无法访问本地磁盘文件系统(由于安全限制)
一种解决方法是,在第二个请求返回
Content-Disposition: attachment
的地方,单击一个按钮即可触发两个HTTP请求,从而使另一个请求的响应保持不变。您可以通过向命令按钮添加onclick
来实现这一点并创建一个大致类似this FileServlet example的PDF servlet。正如您所看到的,不可能通过这种方式调用JSF操作。您必须将PDF下载方法重构为
HttpServlet
类,该类在doGet()
方法中执行任务。对于JSF托管bean和servlet之间的任何必要通信,您可以使用会话范围或传递所需的信息(只是PDF文件标识符?)通过请求路径或参数# 2 楼答案
我通过一个类似的例子,在我的例子中,我使用ajax richfaces标记库和ajax表单标记环绕commandbuton来解决这个问题