Обновить / перейти на текущую страницу при открытии / загрузке файла в новой вкладке / окне


У меня есть кнопка, которая открывает новую вкладку с сгенерированным pdf-файлом. Однако после того, как я нажму на кнопку, Я хочу перейти на другую страницу.

Это означает, что после нажатия на кнопку Я хочу открыть новую вкладку с pdf и перейти на другую страницу на начальной вкладке. Я использую primefaces p:commandButton и пробовал с onclick="window.location.href='www.google.de'", но это не работает. Однако onclick="window.lalert('www.google.de')" работает.

Вот мой код:

<h:form id="transForm" target="_blank">
<p:commandButton  value="Zertifikat erstellen" ajax="false" 
                                label="Speichert die Anmeldung und erstellt ein Zertifikat im PDF-Format"
                                action="#{transportErfassen.generatePDFZertifikat()}"/>

</h:form>

generatePDFZertifikat() создает ли pdf-файл со следующим кодом, я думаю вот Вопрос:

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();

    externalContext.setResponseContentType("application/pdf" );
    externalContext.setResponseHeader("Expires", "0");
    externalContext.setResponseHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
    externalContext.setResponseHeader("Pragma", "public");
    externalContext.setResponseHeader("Content-disposition", "inline; filename="" + fileName +""");
    externalContext.setResponseContentLength(out.length);
    externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", new HashMap<String, Object>());

    //setze explizit auf OK
    externalContext.setResponseStatus(200);     

    OutputStream os = externalContext.getResponseOutputStream();
    os.write(out, 0, out.length);
    os.flush();

    facesContext.responseComplete();       
    facesContext.renderResponse();       
2 3

2 ответа:

Вы в основном пытаетесь отправить 2 ответа на 1 запрос. Это никогда не будет работать в HTTP. Если вы хотите отправить 2 ответа назад, вы должны позволить клиенту каким-то образом запустить 2 запроса. Вы уже искали правильное направление для решения, с небольшой помощью JavaScript можно запускать несколько запросов на одно событие (клик). Однако ваша попытка в onclick не действительна, изменение window.location по щелчку кнопки submit, прямо перед формой submit, полностью прерывает первоначальное действие кнопки, отправляя форму.

Лучше всего сразу перейти к странице результатов, которая, в свою очередь, вызывает JavaScript window.open() При загрузке страницы, указывая на URL-адрес PDF-файла, который вы хотите открыть. А именно, невозможно отправить некоторый HTML / JS код вместе с PDF-файлом, инструктирующим навигацию (поскольку это, очевидно, повредит файл PDF). Это также означает, что вы не можете вернуть PDF непосредственно в форму отправки запроса. Код должен быть переработан таким образом, чтобы PDF-файл можно было получить с помощью последующего запроса GET. Лучше всего использовать простой сервлет. Сгенерированный PDF-файл можно временно хранить на диске или в сеансе, связанном с уникальным ключом, и передавать этот уникальный ключ в виде запроса pathinfo или параметра сервлету в URL window.open().

Вот пример старта:

Начальная форма:

<h:form>
    ...
    <p:commandButton ... action="#{bean.submit}" />
</h:form>

Боб:

public String submit() {
    File file = File.createTempFile("zertifikat", ".pdf", "/path/to/pdfs");
    this.filename = file.getName();

    // Write content to it.

    return "targetview";
}

Вид цели:

<h:outputScript rendered="#{not empty bean.filename}">
    window.open('#{request.contextPath}/pdfservlet/#{bean.filename}');
</h:outputScript>

PDF сервлет (nullchecks etc опущен для краткости; Java 7 предполагается для Files#copy()):

@WebServlet("/pdfservlet/*")
public class PdfServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        File file = new File("/path/to/pdfs", request.getPathInfo().substring(1));
        response.setHeader("Content-Type", "application/pdf");
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"zertifikat.pdf\"");
        Files.copy(file.toPath(), response.getOutputStream());
    }

}

Как сказал Балуск, Refresh/navigate current page и opening downloading file - это два разных ответа, должно быть два повторных запроса. Я столкнулся с подобной проблемой. Я решил его с помощью jsf ajax успешно.

Вот часть моего кода:

XHTML:

<h:commandButton id="download-button" class="download-button"
    value="download">
<f:ajax event="click" execute="@form" render=":msg-area"
    listener="#{myController.checkForDownload}" onevent="checkCallBack" />
</h:commandButton>
<h:commandButton id="download-button2" class="download-button2"
    value="download" style="display: none;"
    action="#{myController.download}">
</h:commandButton>

Javascript:

function checkCallBack(data) {
    var ajaxStatus = data.status;
    switch (ajaxStatus) {
    case "begin":
        break;
    case "complete":
        break;
    case "success":
        document.getElementById('download-form:download-button2').click();
        break;
    }
}

download-button отображает область сообщения на странице и download-button2 запускает метод загрузки. это две разные просьбы. Когда первый запрос будет завершен, будет запущен второй запрос.