Java 下载后如何刷新页面
我有一个commandButton,它将调用一个函数来下载一个文件(标准的东西,如Java 下载后如何刷新页面,java,jsf,refresh,primefaces,Java,Jsf,Refresh,Primefaces,我有一个commandButton,它将调用一个函数来下载一个文件(标准的东西,如InputStream,BufferedOutputStream)。下载成功后,在函数结束时,我更改当前对象的一些值并将其保存到数据库中。所有这些都正常工作。现在,当文件下载完成时,页面的内容不会更新。我必须点击刷新才能看到更新的内容。请帮忙。下面是我的代码的基本结构 文档:托管Bean getDrawings():方法返回图形列表(实体类) CheckedOutBy:实体的属性Drawing <p:data
InputStream
,BufferedOutputStream
)。下载成功后,在函数结束时,我更改当前对象的一些值并将其保存到数据库中。所有这些都正常工作。现在,当文件下载完成时,页面的内容不会更新。我必须点击刷新才能看到更新的内容。请帮忙。下面是我的代码的基本结构
文档
:托管BeangetDrawings()
:方法返回图形列表(实体类)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" />
您可以使用
p:commandButton
组件的update
属性重新渲染下载后要刷新的区域,在本例中为“绘图表”
您基本上希望让客户端触发两个请求。一个用于检索下载,另一个用于刷新新页面。它们不能在单个HTTP请求中完成。由于下载需要同步进行,并且无法从客户端钩住下载的完成,因此没有干净的JSF/JS/Ajax方法在下载完成后更新组件 借助PrimeFaces,您最好的JSF赌注是
...
或
轮询很容易,但我可以想象它会增加不必要的开销。同步下载启动时,不能使用标准JSF/PrimeFaces组件启动它。但是您可以停止它,让它对
呈现的
属性进行自检。从技术上讲,推动是最好的解决方案,但更难开始。PrimeFaces在《用户指南》的第6章中很好地解释了它的用法。好吧,我决定采用上面BalusC的答案/建议,并决定在这里分享我的代码,供“稍后”可能会在这里停留的人使用。仅供参考,我的环境详细信息如下:
TomEE 1.6.0快照(Tomcat 7.0.39)、PrimeFaces 3.5(PrimeFaces推送)、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>
index.xhtml;包含p:插座组件(PrimeFaces Push);如果您正在实现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下载文件时,就会引用该bean方法,所以这是将消息从服务器“推送”到客户端、在客户端上触发javascript、解除对UI的阻止的最佳位置
下面是我的应用程序中完成任务的bean方法。:)
pf_ordersController.refreshDriverWorksheetsToDownload()
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
)onclick标记中使用以下java脚本
示例:
<p:commandButton ajax="false" icon="ui-icon-arrowstop-1-s" onclick="setTimeout('location.reload();', 1000);" action="#{managedBean.downloadMethod}" />
这将在1秒后自动刷新页面,同时,即在刷新之前,您将获得下载文件,根据您的下载响应时间,增加该脚本中的秒数秒不应少于下载响应时间。这是因为
ajax=“false”
(这是下载文件所必需的)。感谢您的输入。我正在读这一章。如果我有更多问题,我会再打给你。感谢您编辑我的帖子,请从h:commandButton
切换到p:commandButton
。我最初把它命名为p:commandButton
,但我担心很多人不会理解它,因为primefaces
tag只有38
评级。这不是评级,这只是到目前为止标记的问题的数量。只要你沿着它标记jsf
,它就会被合适的人发现;)我还是有点模糊。我的p:commmandButton
也变成了这个
。我的实体图形有一个布尔选中的
属性,它本质上告诉我用户选择了哪个图形
。因此,可以选择下载多个图形。因此,我的update
方法在服务器上,我不清楚要将什么推到浏览器上。你认为我应该把checkedOutBy
的整列都写下来,还是想办法弄清楚哪一列需要更新,然后推送它们发送一个分隔/格式化的字符串,你可以在JS代码中进一步处理。JSON格式可能非常适合这里。据primefaces论坛的人士说,目前,我认为Glassfish不支持推送。我想投票是我唯一的选择。您是否介意详细说明您之前说过的:同步下载开始时,您不能使用标准JSF/PrimeFaces组件启动它。但您可以停止它,让它对渲染属性进行自检。
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]);
}
}
<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}" />
actionListener="#{pf_ordersController.refreshDriverWorksheetsToDownload()}"
public String refreshDriverWorksheetsToDownload() {
String returnValue = prepareDriverWorksheetPrompt("download", false);
usersController.pushNotificationToUser("displayLoadingImage(false)");
return returnValue;
}
public void pushNotificationToUser(String notification) {
applicationScopeBean.pushNotificationToUser(notification, user);
}
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 ajax="false" icon="ui-icon-arrowstop-1-s" onclick="setTimeout('location.reload();', 1000);" action="#{managedBean.downloadMethod}" />