FacesContext.getCurrentInstance()在Runnable类中返回null

时间:2010-05-10 14:01:15

标签: jsf nullpointerexception runnable facescontext

我想通过在FacesContext类的FacesContext.getCurrentInstance()方法中调用run()来获取Runnable,但它会返回null

public class Task implements Runnable {

    @Override
    public void run() {
        FacesContext context = FacesContext.getCurrentInstance(); // null!
        // ...
    }

}

这是如何引起的?如何解决?

1 个答案:

答案 0 :(得分:13)

FacesContext作为ThreadLocal变量存储在负责调用FacesServlet的HTTP请求的线程中,FacesContext负责创建FacesContext。该线程通常仅通过JSF托管bean方法。 Runnable在该线程生成的其他线程中不可用。

在其他线程中,您实际上也不需要它。此外,当您的线程启动并独立运行时,底层HTTP请求将立即继续处理HTTP响应然后消失。无论如何,你将无法对HTTP响应做些什么。

您需要以不同方式解决问题。问问自己:你需要什么?获取一些信息?在构建过程中,只需将 信息传递给public class Task implements Runnable { private Work work; public Task(Work work) { this.work = work; } @Override public void run() { // Just use work. } }

以下示例假定您要访问线程中的某个会话作用域对象。

Work work = (Work) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("work");
Task task = new Task(work);
// ...
Runnable

但是,如果您最终需要通知客户,例如线程的工作已经完成,那么你应该寻找一个不同于添加面部消息左右。答案是使用“推”。这可以通过SSE或websockets实现。在这个相关问题中可以找到具体的websockets示例:Real time updates from database using JSF/Java EE。如果您碰巧使用PrimeFaces,请查看 <p:push>。如果您碰巧使用OmniFaces,请查看<o:socket>


对具体问题

无关,手动创建{{1}}并在Java EE Web应用程序中手动生成线程令人震惊。前往以下Q&amp; A,了解所有注意事项及其实际应如何实现: