首页 > 解决方案 > jsf/primeface 中有没有办法下载文件然后更改页面?

问题描述

我在 jsf 项目中使用 primefaces。我需要在用户点击时实现两个动作: - 下载文件 - 做一个后退动作然后改变页面

我尝试了几件事,但没有任何效果,要么我可以下载文件,要么我可以进行后台处理和更改页面,但不能同时执行这两个操作

我试过这段代码:

<p:commandButton id="exportEventLogButton" value="#{msg['avoir.creer']}" ajax="false" title="Export Log" onclick="PrimeFaces.monitorDownload(start, null)">
    <p:fileDownload value="#{avoirMB.download()}"/>
</p:commandButton>
<p:remoteCommand name="start" update="@this" action="#{avoirMB.saveAvoirTotalSsRefac}" />

有人可以帮助我以正确的顺序或使用正确的代码执行操作吗?谢谢

标签: jsfprimefacesdownload

解决方案


你是对的。在属性上设置时,实现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");
    }
}

此解决方案将在按下下载按钮时调用第一个支持 bean 操作,并在下载完成后立即重定向到新页面。

请注意,此代码假定image已设置为某个值。为了简单起见,我选择在这里省略它。

使用 window.location 的替代方法

正如评论中所讨论的,根据您的要求,您也可以window.location.href像这样在完成后直接设置,

<p:commandButton value="Download" ajax="false" 
    onclick="PrimeFaces.monitorDownload(null, function() { window.location.href='newpage';});"
    action="#{downloadBackingBean.onStarted}">

如果您不需要它,这完全消除了服务器端对 ap:remoteCommand和回调的需要。onCompleted


推荐阅读