Можно ли ссылаться на FacesContext из TimerTask или ScheduledExecutorService при запуске приложения? - PullRequest
2 голосов
/ 08 декабря 2011

Я пытаюсь создать функциональность в веб-приложении JSF1.2 / ADF, которое будет периодически и динамически генерировать карту сайта для веб-сайта, на котором будут сотни страниц, содержание которых будет ежедневно меняться.Загвоздка в том, что мне нужно прочитать некоторые настройки из приложения, чтобы использовать их в качестве основы карты сайта, и для этого мне нужен FacesContext.

Вот то, что я пытался сделать: я создал класс, который реализует ServletContextListener и создает экземпляр компонента в области приложения.Этот компонент выполняет тяжелую работу по созданию файла sitemap.xml с использованием FacesContext.Я создал класс, который расширяет TimerTask, который обращается к бину из области приложения, вызывает метод sitemap и планирует будущие события.Когда я запускаю приложение, класс, который реализует ServletContextListener, запускается, и кажется, что bean-компонент создается, но класс, расширяющий TimerTask, никогда не запускается.Любая помощь будет оценена.Если я могу ответить на любые вопросы или если я что-то пропустил, пожалуйста, дайте мне знать.

Вот мои примеры кода:

public class WebhomesApplicationContextListener implements ServletContextListener {
 private static final String attribute = "SiteMapGenerator";
  public void contextInitialized(ServletContextEvent event) {
  SiteMapGenerator myObject = new SiteMapGenerator();
  event.getServletContext().setAttribute(attribute, myObject);
 }
 public void contextDestroyed(ServletContextEvent event) {
  SiteMapGenerator myObject = (SiteMapGenerator) event.getServletContext().getAttribute(attribute);
  event.getServletContext().removeAttribute(attribute);
 }
}

public class SiteMapGenerator {
 public void generateSitemap() {
   // code to generate map...
 }
}

public class Scheduler extends TimerTask {
 public void run() {
  SiteMapGenerator sitemap = (SiteMapGenerator)FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get("SiteMapGenerator");
  sitemap.generateSitemap();
 }
}

class MainApplication {
 public static void main(String[] args) {
  Timer timer = new Timer();
  timer.schedule(
   new Scheduler(),
   1000 * 60);
 }
}

1 Ответ

2 голосов
/ 08 декабря 2011

Нет, вы не можете.FacesContext доступен только в потоке, связанном с запросом сервлета HTTP, URL которого соответствует шаблону URL FacesServlet и вызвал его.Вместо этого просто передайте SiteMapGenerator Scheduler при его построении.

public class Scheduler {

    private SiteMapGenerator sitemap;

    public Scheduler(SiteMapGenerator sitemap) {
        this.sitemap = sitemap;
    }

    // ...
}

SiteMapGenerator наверняка доступен в точке, где вы строите Scheduler.


Не имеет отношения к конкретной проблеме . Настоятельно не рекомендуется использовать TimerTask в приложении Java EE.См. Также Создание потоков в управляемом компоненте JSF для запланированных задач с использованием таймера .

...