h:commandButton множественные действия: загрузить файл и отобразить таблицу ajax

В настоящее время у меня есть 2 кнопки команд и один список. Основываясь на выборе списка, сгенерированный результат может быть показан в загружаемом файле или представлен в виде таблицы HTML. getFile() код основан на учебнике BalusC по обработке PDF, в то время как 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();
}

Кроме того, я хотел бы установить флажок, если, если он установлен, появится диалоговое окно "Сохранить как" и таблица будет отображена. Если этот флажок не установлен, отображается только таблица.

2 ответа

Решение

К сожалению, это невозможно с HTTP. Вы можете отправить только один ответ обратно на запрос. Вы не можете объединить ответ, содержащий файл PDF, и ответ ajax в один ответ. Поскольку это ограничение HTTP, JSF ничего не может сделать для вас. Кроме того, загрузка файла с использованием Ajax вообще невозможна, поскольку JavaScript не может заставить браузер открывать диалоговое окно " Сохранить как" и не иметь доступа к файловой системе локального диска из-за ограничений безопасности.

Обходной путь может состоять в том, чтобы запустить два HTTP-запроса одним нажатием кнопки, когда возвращается второй запрос. Content-Disposition: attachment так что ответ на другой запрос остается без изменений. Вы можете достичь этого, добавив onclick на кнопку команды.

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

и создайте сервлет PDF, который примерно выглядит как этот пример FileServlet. Как видите, этим невозможно вызвать действие JSF. Вы должны изменить метод загрузки PDF в HttpServlet класс, который делает работу в doGet() метод. Для любой необходимой связи между управляемым JSF-компонентом и сервлетом вы можете использовать область сеанса или передать нужную информацию (только идентификатор файла PDF?) По пути или параметру запроса.

Я схожу для аналогичного случая, в моем случае я решен с помощью тега lib ajax richfaces и окружаю командную кнопку с тегом формы 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> 
Другие вопросы по тегам