我目前有2个命令按钮和一个列表框。根据列表框的选择,生成的结果可以显示在可下载的文件中或呈现为HTML表。该getFile()代码基于BalusC的PDF Handling教程,而getTable()set resultTable。
getFile()
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还是另一个动作以ajax结尾facesContext.responseComplete();?
facesContext.responseComplete();
<h:commandButton value="Get Both" action="#{form.getBoth}"> <f:ajax render="result_table" execute="listbox" /> </h:commandButton> getBoth() { getTable(); getFile(); }
另外,我想要一个复选框,如果选中该复选框,则会弹出另存为对话框并呈现表格。如果未选中,则仅呈现表。
不幸的是,HTTP无法实现。每个请求只能发送回一个响应。您不能将包含PDF文件和ajax响应的响应合并为一个响应。由于这是HTTP限制,因此JSF不能为您做任何事情。另外,根本不可能使用Ajax下载文件,因为由于安全限制,JavaScript不能强制浏览器弹出“ 另存为” 对话框,也不能对本地磁盘文件系统进行任何访问。
一种解决方法是单击一次第二个请求返回的位置时,在一次单击按钮上触发 两个 HTTP请求,以使另一个请求Content-Disposition: attachment的响应保持不变。您可以通过onclick在命令按钮上添加一个来实现。
Content-Disposition: attachment
onclick
<h:commandButton onclick="window.location='/context/pdfservlet/filename.pdf'">
并创建一个大致类似于此FileServlet示例的PDF servlet 。如您所见,由此不可能调用JSF操作。您必须将PDF下载方法重构为可完成方法HttpServlet工作的类doGet()。对于JSF托管bean和servlet之间的任何必要通信,您可以使用会话范围或通过请求路径或参数传递所需的信息(只是PDF文件标识符?)。
HttpServlet
doGet()