FacesContext.getCurrentInstance()在Runnable类中返回null [英] FacesContext.getCurrentInstance() returns null in Runnable class

查看:281
本文介绍了FacesContext.getCurrentInstance()在Runnable类中返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to get the FacesContext by calling FacesContext.getCurrentInstance() in the run() method of a Runnable class, but it returns null.

public class Task implements Runnable {

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

}

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

How is this caused and how can I solve it?

推荐答案

FacesContext 存储为

The FacesContext is stored as a ThreadLocal variable in the thread responsible for the HTTP request which invoked the FacesServlet, the one responsible for creating the FacesContext. This thread usually goes through the JSF managed bean methods only. The FacesContext is not available in other threads spawned by that thread.

您实际上也应该在其他线程中不需要它.此外,当线程启动并独立运行时,基础HTTP请求将立即继续处理HTTP响应,然后消失.无论如何,您将无法对HTTP响应进行任何操作.

You should actually also not have the need for it in other threads. Moreover, when your thread starts and runs independently, the underlying HTTP request will immediately continue processing the HTTP response and then disappear. You won't be able to do something with the HTTP response anyway.

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

You need to solve your problem differently. Ask yourself: what do you need it for? To obtain some information? Just pass that information to the Runnable during its construction instead.

下面的示例假定您要访问线程中的某些会话作用域对象.

The below example assumes that you'd like to access some session scoped object in the thread.

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示例可以在以下相关问题中找到:实时使用JSF/Java EE从数据库进行更新.如果您碰巧使用了PrimeFaces,请查看 <p:push> .如果您碰巧使用OmniFaces,请查看 <o:socket> .

If you however ultimately need to notify the client e.g. that the thread's work is finished, then you should be looking for a different solution than e.g. adding a faces message or so. The answer is to use "push". This can be achieved with SSE or websockets. A concrete websockets example can be found in this related question: Real time updates from database using JSF/Java EE. In case you happen to use PrimeFaces, look at <p:push>. In case you happen to use OmniFaces, look at <o:socket>.

无关与具体问题无关,在Java EE Web应用程序中手动创建Runnable并手动生成线程是令人震惊的.前往以下问答,以了解所有警告以及应如何实际做:

Unrelated to the concrete problem, manually creating Runnables and manually spawning threads in a Java EE web application is alarming. Head to the following Q&A to learn about all caveats and how it should actually be done:

  • Spawning threads in a JSF managed bean for scheduled tasks using a timer
  • Is it safe to start a new thread in a JSF managed bean?

这篇关于FacesContext.getCurrentInstance()在Runnable类中返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆