【问题标题】:FacesContext.getCurrentInstance() returns null in Runnable classFacesContext.getCurrentInstance() 在 Runnable 类中返回 null
【发布时间】:2016-04-04 16:48:04
【问题描述】:

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

public class Task implements Runnable {

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

}

这是怎么引起的,我该如何解决?

【问题讨论】:

    标签: jsf nullpointerexception runnable facescontext


    【解决方案1】:

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

    您实际上也不应该在其他线程中需要它。而且,当你的线程独立启动并运行时,底层的 HTTP 请求会立即继续处理 HTTP 响应然后消失。无论如何,您将无法对 HTTP 响应执行任何操作。

    您需要以不同的方式解决问题。问问自己:你需要它做什么?获取一些信息?只需在构造过程中将信息传递给Runnable

    下面的示例假设您想访问线程中的某个会话范围的对象。

    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);
    // ...
    

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


    与具体问题无关,在 Java EE Web 应用程序中手动创建 Runnables 并手动生成线程令人担忧。前往以下问答,了解所有注意事项以及实际应如何完成:

    【讨论】:

      猜你喜欢
      • 2011-06-14
      • 2012-02-26
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2012-11-20
      • 1970-01-01
      相关资源
      最近更新 更多