FacesContext.getCurrentInstance() 在 Runnable 类中返回 null
我试图通过在 Runnable
的 run()
方法中调用 FacesContext.getCurrentInstance()
来获取 FacesContext
> 类,但它返回 null
。
public class Task implements Runnable {
@Override
public void run() {
FacesContext context = FacesContext.getCurrentInstance(); // 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
FacesContext
存储为ThreadLocal
线程中的变量负责调用FacesServlet
的 HTTP 请求,该变量负责创建FacesContext
。该线程通常仅执行 JSF 托管 bean 方法。FacesContext
在该线程生成的其他线程中不可用。实际上,您在其他线程中也不应该需要它。而且,当你的线程启动并独立运行时,底层的HTTP请求将立即继续处理HTTP响应,然后消失。无论如何,您将无法对 HTTP 响应执行任何操作。
你需要以不同的方式解决你的问题。问问自己:你需要它做什么?为了获取一些信息?只需在构建期间将该信息传递给
Runnable
即可。下面的示例假设您想要访问线程中的某些会话范围对象。
然而,如果您最终需要通知客户端,例如线程的工作已完成,那么您应该寻找不同的解决方案,例如添加面部消息等。答案是使用“推”。这可以通过 SSE 或 websockets 来实现。具体的 websockets 示例可以在此相关问题中找到:实时使用 JSF/Java EE 从数据库进行更新。如果您碰巧使用 PrimeFaces,请查看
。如果您碰巧使用 OmniFaces,请查看
< /a>.与具体问题无关,在 Java EE Web 应用程序中手动创建 Runnable 并手动生成线程是令人震惊的。请参阅以下问答,了解所有注意事项以及实际应该如何完成:
The
FacesContext
is stored as aThreadLocal
variable in the thread responsible for the HTTP request which invoked theFacesServlet
, the one responsible for creating theFacesContext
. This thread usually goes through the JSF managed bean methods only. TheFacesContext
is not available in other threads spawned by that thread.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.
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.
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>
.Unrelated to the concrete problem, manually creating
Runnable
s 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: