Обновить / перейти на текущую страницу при открытии / загрузке файла в новой вкладке / окне
У меня есть кнопка, которая открывает новую вкладку с сгенерированным pdf-файлом. Однако после того, как я нажму на кнопку, Я хочу перейти на другую страницу.
Это означает, что после нажатия на кнопку Я хочу открыть новую вкладку с pdf и перейти на другую страницу на начальной вкладке. Я использую primefacesp: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 ответа:
Вы в основном пытаетесь отправить 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 или параметра сервлету в URLwindow.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
запускает метод загрузки. это две разные просьбы. Когда первый запрос будет завершен, будет запущен второй запрос.