2

我正在尝试在 JSF1.2/ADF Web 应用程序中创建功能,该应用程序将定期动态地为一个网站生成一个站点地图,该网站将有数百个页面,其内容每天都会发生变化。问题是我需要从应用程序中读取一些配置以用作站点地图的基础,为此,我需要 FacesContext。

这是我尝试做的事情:我创建了一个实现 ServletContextListener 并实例化应用程序范围 bean 的类。这个 bean 使用 FacesContext 完成繁重的工作来创建 sitemap.xml。我创建了一个扩展 TimerTask 的类,该类从应用程序范围访问 bean,调用站点地图方法并安排未来的发生。当我运行应用程序时,实现 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);
 }
}
4

1 回答 1

2

不,你不能。FacesContext仅在与 URL 匹配的 URL 模式FacesServlet并已调用它的 HTTP servlet 请求关联的线程中可用。相反,只需将其传递SiteMapGeneratorScheduler它的构造。

public class Scheduler {

    private SiteMapGenerator sitemap;

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

    // ...
}

SiteMapGenerator您构建Scheduler.


与具体问题无关,强烈建议不要TimerTask在 Java EE 应用程序中使用它。另请参阅在 JSF 托管 bean 中为使用计时器的计划任务生成线程

于 2011-12-07T22:31:33.403 回答