如何在下载后刷新页面

我有一个commandButton,它将调用一个函数来下载一个文件(标准的东西,比如InputStreamBufferedOutputStream ……)下载成功后,在函数结束时,我改变了当前对象的一些值并将其保存到数据库中。 所有这些都正常工作。 现在,当文件下载完成时,页面内容不会更新。 我必须点击刷新才能看到更新的内容。 请帮忙。 以下是我的代码的基本结构

document :Managed Bean
getDrawings() :方法返回一个Drawing列表(实体类)
CheckedOutBy :实体Drawing属性

 

...

在我的Managed Bean里面

 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方法来更新组件。

在PrimeFaces的帮助下,你最好的JSF-bet是

  ...  

或者

  

轮询很容易,但我可以想象它增加了不必要的开销。 在同步下载开始时,您无法使用标准JSF / PrimeFaces组件启动它。 但是你可以阻止它让它自己检查rendered属性。 推送在技术上是最好的解决方案,但更难以开始。 PrimeFaces在用户指南的第6章中很好地解释了它的用法。

好吧,我决定采用上面的BalusC的回答/建议,并决定在这里分享我的代码给那些可能会在这里停留的人,“以后”。 仅供参考,我的环境详情如下:

TomEE 1.6.0 SNAPSHOT(Tomcat 7.0.39),PrimeFaces 3.5(PrimeFaces推送),Atmosphere 1.0.13快照(1.0.12是最新稳定版)

首先,我使用p:fileDownload和p:commandLink。

    

由于我上面有xhtml,并且因为p:fileDownload不允许执行oncomplete =“someJavaScript()”,所以我决定使用PrimeFaces Push将消息推送到客户端,以触发解锁UI所需的javascript,因为UI当我点击commandLink下载文件时被阻止,并且好几个月,我不知道如何解决这个问题。

由于我已经在使用PrimeFaces Push,我不得不在客户端调整以下内容:

.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]); } } 

的index.xhtml; 包含p:socket组件(PrimeFaces Push); 如果你正在实现PrimeFaces Push的FacesMessage示例,我建议以下所有内容

    

几个月(或者可能是一年左右)之前,我发现有必要将以下内容添加到包装p:fileDownload的commandLink中,这将刷新服务器上的文件/流,因此您可以多次单击该文件您需要并一次又一次地下载文件,而无需通过键盘上的F5 /刷新键(或移动设备上的类似键)刷新页面

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

每当最终用户单击commandLink以下载文件时,都会引用该bean方法,因此这是将服务器“推送”到客户端,在客户端上触发javascript以取消阻止UI的最佳位置。

以下是我的应用程序中完成工作的bean方法。 🙂

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; } } } 

您可以使用p:commandButton组件的update属性重新渲染下载后要刷新的区域,在本例中为“drawing_table”。

  

正如Balusc回答的那样,我们无法从单个请求中获得两次响应。

要在下载后刷新页面,请在下载链接( p:commandbuttononclick标记中更好地使用以下java脚本。

例:

  

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