Вы правы. Реализация p:remoteCommand
, по-видимому, не поддерживает перенаправление страниц, если установлено для атрибута action=""
. Я попробовал несколько разных вариантов, и мне это совсем не нравится.
Решение состоит в том, чтобы программно перенаправить, когда JSF и p:remoteCommand
вызывают обратный вызов действия (это проверено с Lombok и PrimeFaces 6.2);
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form>
<p:remoteCommand process="@this" action="#{downloadBackingBean.onCompleted}" name="stop" />
<p:commandButton value="Download" ajax="false" onclick="PrimeFaces.monitorDownload(null, stop);" action="#{downloadBackingBean.onStarted}">
<p:fileDownload value="#{downloadBackingBean.image}" />
</p:commandButton>
</h:form>
</h:body>
@Data
@Named
@RequestScoped
public class DownloadBackingBean {
private StreamedContent image;
public void onStarted() {
System.out.println("download started");
}
public void onCompleted() throws IOException {
System.out.println("download completed");
FacesContext.getCurrentInstance().getExternalContext().redirect("newpage");
}
}
Это решение вызовет первое действие компонента поддержки при нажатии кнопки загрузки и перенаправит на новую страницу, как только загрузка будет завершена.
Обратите внимание, что в этом коде предполагается, что image
установлен на что-то. Ради простоты я решил опустить это здесь.
Альтернативный метод с использованием window.location
Как обсуждалось в комментариях, в зависимости от ваших требований, вы также можете просто установить window.location.href
сразу после завершения, например,
<p:commandButton value="Download" ajax="false"
onclick="PrimeFaces.monitorDownload(null, function() { window.location.href='newpage';});"
action="#{downloadBackingBean.onStarted}">
Это полностью устраняет необходимость в обратном вызове p:remoteCommand
и onCompleted
на стороне сервера, если он вам не нужен.