使用结果更新在服务器上异步运行ajax请求

时间:2014-04-09 07:49:21

标签: java ajax jsf jsf-2 primefaces

我有一个使用Primefaces 4在Tomcat 7上运行Java 6的JSF Web应用程序。我已经处理了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调用(点击按钮)立即返回,这样用户可以继续摆弄,并在一段时间之后弹出错误消息 - 一旦长期采取的东西是完成。但是,使用ExecutorService将所有内容放入Runnable似乎不起作用。至少,FacesContext在新线程中不可用/工作。

我无法想象我是第一个遇到这个问题的人。然而,我似乎无法找到解决方案。有没有类似最佳实践的东西,或者我错过了Primefaces或JSF为这些情况提供的明显的东西?

为了记录,我了解PrimePush。这可能是在必要时推回错误消息的解决方案。但是我如何处理线程以及何时以及如何检查是否可以显示错误消息?

TIA!

1 个答案:

答案 0 :(得分:0)

我认为,你正走在正确的道路上。 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。