h:commandButton 多个动作:下载文件并渲染ajax表 [英] h:commandButton multiple actions: download file and render ajax table

查看:18
本文介绍了h:commandButton 多个动作:下载文件并渲染ajax表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有 2 个命令按钮和一个列表框.根据列表框选择,生成的结果可以显示在可下载的文件中或呈现为 HTML 表格.getFile() 代码基于 BalusC 的 PDF 处理教程,而 getTable() 设置 resultTable.

I currently have 2 command buttons and one listbox. Based on listbox selection, the result generated can be shown in a download-able file or rendered as an HTML table. The getFile() code is based on BalusC's PDF Handling tutorial, while getTable() sets 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(); 结束?

Both buttons are working fine so far. However, I want to combine both actions into one button. When I test this out with a button that fires off both actions, nothing happens (no file save as dialog or table rendered). Is this because one action is ajax or because the other action finishes with facesContext.responseComplete();?

<h:commandButton value="Get Both" action="#{form.getBoth}">
    <f:ajax render="result_table" execute="listbox" />
</h:commandButton>

getBoth() {
    getTable();
    getFile();
}

另外,我想要一个复选框,如果选中它,则会弹出另存为对话框并呈现表格.如果未选中,则仅呈现表格.

Additionally I would like a checkbox where if it is checked, save as dialog pops up and table is rendered. If it is not checked, only table is rendered.

推荐答案

不幸的是,HTTP 无法做到这一点.每个请求只能发回一个响应.您不能将包含 PDF 文件的响应和 ajax 响应合并为一个响应.由于这是 HTTP 限制,JSF 不能为您做任何事情.此外,根本不可能使用 Ajax 下载文件,因为 JavaScript 无法强制浏览器弹出另存为对话框,也无法访问本地磁盘文件系统,因为安全限制.

Unfortunately, that's not possible with HTTP. You can send only one response back per request. You cannot merge the response containing the PDF file and the ajax response into one response. Since this is a HTTP restriction, JSF can't do any much for you. Also, downloading a file using Ajax is not possible at all since JavaScript can't force the browser to pop a Save As dialogue nor have any access to local disk file system due to security restrictions.

一种解决方法是在单击一次按钮时触发 两个 HTTP 请求,其中第二个请求返回 Content-Disposition:attachment 以便另一个请求的响应保持原封不动.您可以通过向命令按钮添加 onclick 来实现此目的.

A workaround would be to fire two HTTP requests on a single button click where the second request returns Content-Disposition: attachment so that the response of the other request keeps untouched. You can achieve this by adding an onclick to the command button.

<h:commandButton onclick="window.location='/context/pdfservlet/filename.pdf'">

并创建一个 PDF servlet,大致类似于 这个 FileServlet 示例.如您所见,不可能通过此调用 JSF 操作.您必须将 PDF 下载方法重构为在 doGet() 方法中完成工作的 HttpServlet 类.对于 JSF 托管 bean 和 servlet 之间的任何必要通信,您可以使用会话范围或通过请求路径或参数传递所需的信息(只是 PDF 文件标识符?).

and create a PDF servlet which roughly look like this FileServlet example. As you see, it's not possible to invoke a JSF action by this. You have to refactor the PDF download method to a HttpServlet class which does the job in doGet() method. For any necessary communication between the JSF managed bean and the servlet, you could use the session scope or pass the desired information (just the PDF file identifier?) by request path or parameter.

这篇关于h:commandButton 多个动作:下载文件并渲染ajax表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆