Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring异步任务:更新jsf视图组件_Spring_Jsf_Asynchronous - Fatal编程技术网

Spring异步任务:更新jsf视图组件

Spring异步任务:更新jsf视图组件,spring,jsf,asynchronous,Spring,Jsf,Asynchronous,我有一个长期运行的作业必须在后台运行,完成后我想更新jsf视图组件 我使用了SimpleAsyncTaskExecutor来完成这项工作。它工作得很好,但是当提交到更新ui时,我得到了NullPointerException 这是我的密码 SimpleAsyncTaskExecutor tasks = new SimpleAsyncTaskExecutor(); tasks.submitListenable(new Callable<String>() { @Overri

我有一个长期运行的作业必须在后台运行,完成后我想更新jsf视图组件

我使用了
SimpleAsyncTaskExecutor
来完成这项工作。它工作得很好,但是当提交到更新ui时,我得到了
NullPointerException

这是我的密码

SimpleAsyncTaskExecutor tasks = new SimpleAsyncTaskExecutor(); 
tasks.submitListenable(new Callable<String>() {

    @Override
    public String call() throws Exception {
        //Do long time taking job in approximately 16 seconds
        doTheBigJob();

        //then update view component by it's id
        FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(myComponentId);
        return "";          
    }       
});
SimpleAsyncTaskExecutor任务=新的SimpleAsyncTaskExecutor();
tasks.submitListenable(newcallable()){
@凌驾
公共字符串调用()引发异常{
//在大约16秒内完成长时间的作业
doTheBigJob();
//然后根据视图组件的id更新视图组件
FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(myComponentId);
返回“”;
}       
});
否:当时间较短(如2秒)时,不会发生
NullPointerException


感谢您的建议。

FacesContext.getCurrentInstance()
返回
null
,因为它试图从中获取上下文。但由于执行线程不是由JSF初始化的(由
javax.faces.webapp.FacesServlet
完成),而是由executor创建的,因此线程局部变量是
null

我不知道为什么
NullPointerException
有时不会发生。默认情况下,
SimpleAsyncTaskExecutor
每次都创建新线程,除非指定线程池。当我重新创建示例时,每次都会发生。可能有,但没有正确记录

为了解决你的问题,你需要求助于投票。例如,您可以使用backingbean的属性来指示作业已完成

@Named("someBean")
@SessionScoped
public class SomeBean {
    private volatile boolean jobDone = false;

    public String execute() {
        SimpleAsyncTaskExecutor tasks = new SimpleAsyncTaskExecutor(); 
        tasks.submitListenable(new Callable<String>() {

            public String call() throws Exception {
                //Do long time taking job in approximately 16 seconds
                doTheBigJob();
                jobDone = true
                return "";          
            }       
        });
        return null;
    }

    public boolean isJobDone() {
        return jobDone;
    }

}
然后使用轮询和AJAX更新当前页面

在纯JSF中,进行轮询的唯一方法是结合使用JavaScript和JSF AJAX请求

或者,您可以使用Primefaces组件轮询更改

<p:poll interval="1" update="jobDoneText" />


关于JSF中轮询的更多信息可以在以下问题的答案中找到:

这里没有spring知识,但我怀疑这是否会起作用。我知道如何从异步调用(ejb,而不是spring)更新视图的唯一方法是使用基于websockets的推送机制,例如atmosphere(这样就可以对旧客户端进行回退)谢谢你的建议,但Dawit的答案正是我想要的:-)他写的正是我想要写的,如果我写了一个完整的答案,他建议投票(p:poll),我会建议WebSocket(p:socket)。但很好,它的工作
<p:poll interval="1" update="jobDoneText" />