Я пытаюсь добраться FacesContext
путем вызова FacesContext.getCurrentInstance()
в run()
метод a Runnable
класс, но это возвращается null
.
public class Task implements Runnable {
@Override
public void run() {
FacesContext context = FacesContext.getCurrentInstance(); // null!
// ...
}
}
Как это вызывается и как я могу решить его?
FacesContext
хранится как ThreadLocal
в потоке, отвечающем за HTTP-запрос, который вызвал FacesServlet
, ответственный за создание FacesContext
. Этот поток обычно проходит только через методы управляемого компонента JSF. 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 или веб-сокетов. Конкретный пример веб-сокетов можно найти в этом связанном вопросе: Обновления в реальном времени из базы данных с использованием JSF / Java EE . Если вы используете PrimeFaces, посмотрите
.Если вы используете OmniFaces, посмотрите
.
Не связанный с конкретной проблемой, создание вручную Runnable
и ручное создание потоков в веб-приложении Java EE вызывает тревогу. Прочтите следующие вопросы и ответы, чтобы узнать обо всех предостережениях и о том, как это должно быть сделано на самом деле: