我有一个JSF web应用程序,它使用Primefaces 4,在Tomcat 7上运行Java 6。我已经处理了ajax调用和框架提供的所有闪亮的东西,但我一直在做一个需要在服务器端进行长时间处理的ajax请求,这真的是异步的。
public void onMyButtonClicked() {
try {
doSomethingThatTakesLong();
} catch (Exception e) {
final FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_WARN, "Exception caught", "Explanatory message"));
}
}
每当我的用户点击花哨的按钮时,就会发生一些真正需要很长时间的事情。不幸的是,有些事情甚至可能出错,我需要显示一条错误消息。到目前为止,这一切都在起作用。
我需要更改的内容很简单:我希望ajax调用(单击按钮)立即返回,这样用户就可以继续摆弄,并在一段时间后弹出错误消息——一旦完成了漫长的操作。不过,仅仅使用Runnable
将所有内容放入ExecutorService
似乎并不奏效。至少,FacesContext
不可用/无法从新线程工作。
我无法想象我是第一个有这个问题的人。然而,我似乎找不到解决办法。有没有类似于最佳实践的东西,或者我错过了Primefaces或JSF为这些情况提供的一些明显的东西?
郑重声明,我知道PrimePush。这可能是在必要时推回错误消息的解决方案。但是,我该如何处理线程,何时以及如何检查是否可以显示错误消息?
TIA!
我认为,你走在了正确的道路上。FacesContext
仅在请求范围内可用,更具体地说,在处理请求的线程内可用(因为FacesContext
是线程本地的),即肯定不在您的Runnable
内。但是,你当然可以把它注入你的Runnable
。
对于错误消息,PrimePush
应该可以正常工作。如果是ExecutorService
,请尝试以下操作:
public void onMyButtonClicked() {
final FacesContext context = FacesContext.getCurrentInstance();
executorService.execute(new Runnable() {
@Override
public void run() {
try {
// You can probably use facesContext here
doSomethingThatTakesLong();
} catch (Exception e) {
final PushContext pushContext = PushContextFactory.getDefault().getPushContext();
pushContext.push("/errors", new FacesMessage(FacesMessage.SEVERITY_WARN, "Exception caught", "Explanatory message"));
}
}
});
}
现在设置你的PrimePush
在/errors
频道上做任何你想做的事情,可能会通过javascript或其他方式更新你的Growl。