Рендеринг, инициируемый сервером: EJB -> FacesContext? - PullRequest
2 голосов
/ 20 апреля 2010

Я уже задавал этот вопрос на форуме Icefaces, но тем временем я понял, что это более общая проблема.

Я бы хотел обновить части страницы JSF при получении сообщения в моем MDB.

Проблема в том, как мне получить FacesContext из контейнера EJB?

В функции обработки сообщений FacesContext.getCurrentInstance () возвращает ноль.

Я также пытался превратить управляемый компонент JSF в MDB, но не смог (кажется, вы не можете иметь оба в одном классе?)

Поскольку я новичок в мире JSF, я застрял сейчас. Есть ли способ заставить его работать?

(Glassfish v3 + Netbeans 6.8, JSF2 + Icefaces 2.0 alpha2)

Ответы [ 4 ]

2 голосов
/ 20 апреля 2010

FacesContext основан на HTTP-запросе и, таким образом, доступен только во время обработки HTTP-запроса и даже тогда, только когда URL-адрес запроса соответствует шаблону URL-адреса FacesServlet. Если вы не в потоке, который выполняется сервером для обработки HTTP-запроса, значит, FacesContext также не существует. В контейнере EJB нет абсолютно никаких средств HTTP-запросов.

Технически, единственный способ сообщить EJB JSF о новом сообщении - это позволить EJB запустить HTTP-запрос по URL-адресу, совпадающему с шаблоном URL-адреса FacesServlet, с сообщением в качестве параметра запроса. Вы можете использовать java.net.URLConnection для этого. JSF, в свою очередь, может затем выполнить push-обработку Comet / HTTP, чтобы обновить представление сообщением IceFaces, как вы упомянули.

* 1006 Е.Г. *

URL url = new URL("http://example.com/context/poll.jsf?msg=" + URLEncoder(msg, "UTF-8"));
URLConenction connection = url.openConnection();
InputStream response = connection.getInputStream();

и poll.jsf, который прикреплен к поддерживающему компоненту следующим образом:

@ManagedBean
public class Poll {

    @ManagedProperty(value="#{param.msg}")
    private String msg;

    @PostConstruct
    public void init() {
        // Do something with msg.
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

Примечание. Используются аннотации JSF 2.0, но они должны быть достаточно понятны.

1 голос
/ 20 апреля 2010

Я не эксперт, но я ожидаю, что FacesContext доступен только во время обработки запроса JSF. Боюсь, вы не можете делать именно то, что вы хотите, но вы, безусловно, можете обойти это. На самом деле есть две проблемы:

  1. Как получить обновление через MDB на страницу JSF?
  2. Как обновить страницу на клиенте, когда происходит событие? Вы не может нормально отправлять данные с сервера на клиент, клиент должен требуйте их (хотя есть некоторые обходные пути, такие как http://en.wikipedia.org/wiki/Comet_(programming)))

Я бы что-то вроде следующего:

  1. В MDB храните обновленные данные где-нибудь - например, в глобальном кэше (сессионный компонент без сохранения состояния с @Singleton и коллекция или карта для обновлений)
  2. Измените страницу JSF, чтобы она регулярно запрашивала у сервера обновления (предпочтительно в фоновом режиме с использованием Ajax через некоторый компонент JSF с поддержкой ajax) - если есть обновление, полученное через MDB, сервер вернет его и страница будет перерисована
0 голосов
/ 21 апреля 2010

Я также получил ответ на форуме Icefaces:

org.icefaces.application.PortableRenderer предоставляет объект, который можно использовать в потоках не-JSF для вызова push. (Это доступно в стволе svn и будет предоставлено в следующей альфа-версии (= Icefaces 2.0 alpha 3).)

0 голосов
/ 20 апреля 2010

У меня есть обходной путь, который включает таймер на стороне JSF (к счастью, он находится только на сервере, никакой связи AJAX и клиент-сервер не требуется), который проверяет Singleton и при необходимости запускает обновления. Однако я все еще считаю, что это не правильное решение и что это может быть сделано без таймера ...

...