Spring AsyncTask:更新jsf视图组件

Ism*_*hin 4 jsf spring asynchronous

我有一个长期工作必须在后台运行,完成后我想更新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 "";          
    }       
});
Run Code Online (Sandbox Code Playgroud)

不是:当时间很短(如2秒)时,不会NullPointerException发生

谢谢你的到来.

Daw*_*tel 7

FacesContext.getCurrentInstance()返回,null因为它尝试从线程局部变量获取上下文.但是因为执行线程没有被JSF初始化(由其完成javax.faces.webapp.FacesServlet),而是由执行器创建,然后是线程局部变量null.

我不知道为什么NullPointerException有时不会发生.SimpleAsyncTaskExecutor除非您指定线程池,否则默认情况下每次都会创建新线程.当我重新创建这个例子时,它每次都会发生.也许它确实没有正确记录......

要解决您的问题,您需要求助于轮询.例如,您可以使用辅助bean的属性来指示作业已完成.

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

在您的页面上输入在何时呈现的组件jobDone==true.例如:

<h:outputText id="jobDoneText" rendered="#{someBean.jobDone}" value="Job finished"/>
Run Code Online (Sandbox Code Playgroud)

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

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

或者,您可以使用Primefaces组件p:poll轮询更改.

<p:poll interval="1" update="jobDoneText" />
Run Code Online (Sandbox Code Playgroud)

有关JSF中轮询的更多信息可以在以下问题的答案中找到:JSF,定期刷新带有ajax的组件?