是否可以在应用程序启动时从 TimerTask 或 ScheduledExecutorService 引用 FacesContext?
我正在尝试在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,你不能。
FacesContext
仅在与 HTTP servlet 请求关联的线程中可用,该请求的 URL 与FacesServlet
的 URL 模式匹配并已调用它。相反,只需在构造时将SiteMapGenerator
传递给Scheduler
即可。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 theFacesServlet
and has invoked it. Instead, just pass theSiteMapGenerator
to theScheduler
on its construction.The
SiteMapGenerator
is surely available at the point you're constructing theScheduler
.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.