是否可以在应用程序启动时从 TimerTask 或 ScheduledExecutorService 引用 FacesContext?

发布于 2024-12-19 20:27:07 字数 1511 浏览 2 评论 0原文

我正在尝试在 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);
 }
}

I am attempting to create functionality in a JSF1.2/ADF web app that will periodically & dynamically generate a sitemap for a website that will have hundreds of pages whose content will change daily. The catch is that I need to read some config from the application to use as the basis of the sitemap and to do so, I need FacesContext.

Here is what I have attempted to do: I created a class that implements a ServletContextListener and instantiates an application scoped bean. This bean does the heavy lifting to create sitemap.xml using FacesContext. I created a class that extends TimerTask that accesses the bean from application scope, calls the sitemap method and schedules future occurrences. When I run the application, the class that implements ServletContextListener fires and the bean appears to be created, but the class that extends TimerTask is never fired. Any help would be appreciated. If I can answer any questions or if I left anything out, please let me know.

Here are my code samples:

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);
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话难免假 2024-12-26 20:27:07

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

public class Scheduler {

    private SiteMapGenerator sitemap;

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

    // ...
}

SiteMapGenerator 在您构建 Scheduler 时肯定可用。


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

No, you can't. The FacesContext is only available in the thread associated with the HTTP servlet request whose URL matched the URL pattern of the FacesServlet and has invoked it. Instead, just pass the SiteMapGenerator to the Scheduler on its construction.

public class Scheduler {

    private SiteMapGenerator sitemap;

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

    // ...
}

The SiteMapGenerator is surely available at the point you're constructing the Scheduler.


Unrelated to the concrete problem, It's strongly discouraged to use TimerTask in a Java EE application. See also Spawning threads in a JSF managed bean for scheduled tasks using a timer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文