Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
196 views
in Technique[技术] by (71.8m points)

java - h:commandButton multiple actions: download file and render ajax table

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>

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

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'">

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...