题
我有命令按钮,将调用一个功能下载一个文件(标准的东西喜欢 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秒钟后自动刷新页面,同时在刷新之前,您将根据下载响应时间获得下载文件,并增加该脚本中的秒数。 秒不应少于该下载响应时间。