我有命令按钮,将调用一个功能下载一个文件(标准的东西喜欢 InputStream, BufferedOutputStream ...)下载后成功,在结束的功能,我改变一些价值观目前的目的和持续存入数据库。所有这些工作是正确的。现在,当文件是完成下载,网页的内容不会更新。我必须打刷新对我看到更新的内容。请帮助。下面的基本结构的我的代码

document:管理豆
getDrawings():法返回的一个列表中绘制(实体类)
CheckedOutBy:属性的实体 Drawing

<p:dataTable id="drawing_table" value="#{document.drawings}" var="item" >                            
    <p:column>
        <f:facet name="header">
              <h:outputText value="CheckedOutBy"/>
        </f:facet>
        <h:outputText value="#{item.checkedOutBy}"/>
        ...
</p:dataTable>
<p:commandButton ajax="false" action="#{document.Download}" value="Download" />

在我的管理豆

public void Download(){
    Drawing drawing = getCurrentDrawing();
    //Download drawing
    drawing.setCheckedOutBy("Some Text");
    sBean.merge(drawing);  //Update "Some Text" into CheckedOutBy field
}
有帮助吗?

解决方案

您基本上想让客户开火 要求。一个用于检索下载,另一个用于刷新新页面。它们不能在单个HTTP请求中完成。由于下载需要同步进行,并且无法从客户端开始完成下载,因此没有干净的JSF/JS/AJAX方法可以在下载完成后更新组件。

最好的JSF-BET在Primefaces的帮助下是 <p:poll>

<h:outputText id="checkedOutBy" value="#{item.checkedOutBy}"/>
...
<p:poll id="poll" interval="5" update="checkedOutBy" />

或者 <p:push>

<p:push onpublish="javaScriptFunctionWhichUpdatesCheckedOutBy" />  

投票很容易,但我可以想象它增加了不必要的开销。当同步下载开始时,您不能使用标准JSF/PrimeFaces组件启动它。但是您可以阻止它让它对 rendered 属性。从技术上讲,推动是最好的解决方案,但开始更艰难。 PrimeFaces在用户指南的第6章中解释了它的使用。

其他提示

嗯,我决定去BalusC的答案/项建议上,决定与大家分享我的代码这里的人可以停在这里,'以后'.仅供参考,我的环境,详情如下:

关于这些1.6.0快照(Tomcat7.0.39),PrimeFaces3.5(PrimeFaces推),气氛1.0.13快照(1.0.12是稳定的最新版本)

第一,我使用的p:fileDownload p:commandLink.

<p:commandLink value="Download" ajax="false"
               actionListener="#{pf_ordersController.refreshDriverWorksheetsToDownload()}">
    <p:fileDownload value="#{driverWorksheet.file}"/>
</p:commandLink>

因为我有xhtml上,由于p:fileDownload不允许oncomplete="someJavaScript()"待执行,我决定使用PrimeFaces推来推动信息要客户,以触发javascript有必要解除封锁,因为UI受阻每当我击commandLink下载文件,并且对许多个月来,我不知道如何来解决这个问题。

因为我已经使用PrimeFaces的推动,我不得不调整以下的客户面:

.js文件;中包含的方法处理消息推从服务器的客户

function handlePushedMessage(msg) {
    /* refer to primefaces.js, growl widget,
     * search for: show, renderMessage, e.detail
     * 
     * sample msg below:
     * 
     * {"data":{"summary":"","detail":"displayLoadingImage(false)","severity":"Info","rendered":false}}
     */
    if (msg.detail.indexOf("displayLoadingImage(false)") != -1) {
        displayLoadingImage(false);
    }
    else {
        msg.severity = 'info';
        growl.show([msg]);
    }
}

索引。xhtml;包含p:插槽组件(PrimeFaces推);我建议以下所有,如果你正在实施FacesMessage例PrimeFaces推

<h:outputScript library="primefaces" name="push/push.js" target="head" />
<p:growl id="pushedNotifications" for="socketForNotifications"
         widgetVar="growl" globalOnly="false"
         life="30000" showDetail="true" showSummary="true" escape="false"/>
<p:socket id="socketForNotifications" onMessage="handlePushedMessage"
          widgetVar="socket"
          channel="/#{pf_usersController.userPushChannelId}" />

几个月(或者可能一年或使)前,我发现有必要添加以下的commandLink,包p:fileDownload,这将刷新文件/流服务器上,这样你可以击该文件多次因为你需要下载的文件一而再,再而不刷新的网页通过F5/刷新键盘(或类似的移动装置)

actionListener="#{pf_ordersController.refreshDriverWorksheetsToDownload()}"

那豆方法被引用,只要最终用户击commandLink,下载文件,因此这是完美的现场"推"的消息从服务于客户,触发javascript上的客户,解除封锁。

下面是豆的方法在我的应用程序,能够完成任务。:)

pf_ordersController.refreshDriverWorksheetsToDownload()

public String refreshDriverWorksheetsToDownload() {
    String returnValue = prepareDriverWorksheetPrompt("download", false);
    usersController.pushNotificationToUser("displayLoadingImage(false)");
    return returnValue;
}

usersController.pushNotificationToUser();我不得不添加这一次,今晚。

public void pushNotificationToUser(String notification) {
    applicationScopeBean.pushNotificationToUser(notification, user);
}

applicationScopeBean.pushNotificationToUser();这已经存在,没有改变这种方法。

public void pushNotificationToUser(String msg, Users userPushingMessage) {
    for (SessionInfo session : sessions) {
        if (userPushingMessage != null &&
            session.getUser().getUserName().equals(userPushingMessage.getUserName()) &&
            session.getUser().getLastLoginDt().equals(userPushingMessage.getLastLoginDt())) {
            PushContext pushContext = PushContextFactory.getDefault().getPushContext();
            pushContext.push("/" + session.getPushChannelId(),
                             new FacesMessage(FacesMessage.SEVERITY_INFO, "", msg));
            break;
        }
    }
}

您可以使用 update 属性 p:commandButton 重新渲染您打算在下载后打算刷新的区域的组件,在这种情况下,您的“ drawit_table”。

<p:commandButton update="drawing_table" action="#{document.Download}" value="Download" />

作为 balusc 回答,我们无法从单个请求中获得两次响应。

要在下载后刷新页面,请在下载链接中更好地使用以下Java脚本(p:commandbutton) onclick标签.

例子:

<p:commandButton ajax="false" icon="ui-icon-arrowstop-1-s" onclick="setTimeout('location.reload();', 1000);" action="#{managedBean.downloadMethod}" />

这将在1秒钟后自动刷新页面,同时在刷新之前,您将根据下载响应时间获得下载文件,并增加该脚本中的秒数。 秒不应少于该下载响应时间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top