好吧,我决定接受上面 BalusC 的回答/建议,并决定在此处分享我的代码,以供可能“稍后”在这里停留的人使用。仅供参考,我的环境详细信息如下:
TomEE 1.6.0 SNAPSHOT (Tomcat 7.0.39)、PrimeFaces 3.5 (PrimeFaces Push)、Atmosphere 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 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]);
}
}
索引.xhtml;包含 p:socket 组件(PrimeFaces Push);如果您正在实施 PrimeFaces Push 的 FacesMessage 示例,我推荐以下所有内容
<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}" />
几个月(或一年左右)前,我发现有必要将以下内容添加到包装 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;
}
}
}