我想在线程中发生异常时在浏览器中显示友好的错误消息。我在xhtml页面中有(类似于h:message)。它只显示来自同一线程的消息,但在此方案中不起作用。如何在不保存线程的情况下使其工作,因为该方法应该异步执行?
public void start(final Land lan)
{
try {
Future future = executor.submit(new Callable(){
@Override
public Object call() {
try {
conversion.processLand(lan);
LOG.debug("Finished the execution serverion");
uploadLandPages(lan.getPages(),
lan.getLandOID());
}catch(LanException doc){
LOG.error("LanException is caused due to "+doc.getMessage());
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"File Conversion Issue","Unfortunately we cannot convert this file, please try again later"));
} catch (ApplicationException apx) {
LOG.error("ApplicationException is caused due to "+apx.getMessage());
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"File Conversion Issue", "We have successfully converted the file but couldn't save in our server"));
}
return null;
}
});
} catch(Exception e){
LOG.error("Exception caused in the thread which converts the doc due to {}",e.getMessage());
throw new RuntimeException("Couldn't create the Conversion thread");
}
finally {
executor.shutdown();
}
}
答案 0 :(得分:3)
它不起作用,因为消息必须进入HTTP响应。当您将服务于HTTP请求的线程保留为异步运行时,您显然会失去对HTTP响应的控制权。更重要的是,FacesContext
在其他线程中根本不可用。特定代码只会以NullPointerException
结尾。
你基本上有两种选择:
使用投票。您可以使用<p:poll>
。只要存在非空消息,就会间隔轮询到会话范围的bean。然后删除并显示它并停止轮询。执行程序服务应将消息设置为该会话作用域bean的属性。
使用推送。您可以使用<p:socket>
(PrimePush)。执行者应通过PushContext#push()
在<p:socket channel>
标识的唯一渠道名称上设置消息(当前用户独有!或者可能反映给所有用户)。
无关具体问题,因为您似乎已经在使用Java EE,我建议使用@Asynchronous
EJB方法而不是执行服务,如果可能的话。这样线程就由容器本身管理和汇集。