さて、私は上記の BalusC の回答/推奨事項に従うことにし、「後で」ここに立ち寄る可能性のある人々のために、ここでコードを共有することにしました。参考までに、私の環境の詳細は以下のとおりです。
TomEE 1.6.0 SNAPSHOT (Tomcat 7.0.39)、PrimeFaces 3.5 (PrimeFaces Push)、Atmosphere 1.0.13 スナップショット (1.0.12 が最新の安定バージョン)
まず、p:commandLink で p:fileDownload を使用しています。
<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 をトリガーすることにしました。 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 の例を実装している場合は、次のすべてをお勧めします。
<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}" />
数か月前 (またはおそらく 1 年ほど前)、p:fileDownload をラップする commandLink に次を追加する必要があることがわかりました。これにより、サーバー上のファイル/ストリームが更新され、ファイルを何度でもクリックできるようになります。キーボードの F5/refresh キー (またはモバイル デバイスの同様のキー) を使用してページを更新せずに、ファイルが必要であり、何度もダウンロードします。
actionListener="#{pf_ordersController.refreshDriverWorksheetsToDownload()}"
その Bean メソッドは、エンドユーザーが commandLink をクリックしてファイルをダウンロードするたびに参照されるため、サーバーからクライアントにメッセージを「プッシュ」し、クライアントで 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;
}
}
}