2013-07-03 134 views
0

我试图通过使用方法getResourcePaths() in ExternalContext获取WAR文件中的资源路径。但如果该方法被@Schedule调用,该怎么办?在这种情况下,FacesContext为空。如何在没有FacesContext的情况下获取资源路径?

@Schedule(hour = "*", minute = "0,30", second = "0") 
public void foo() { 
    ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext(); 
    Set<String> resources = ctx.getResourcePaths("/WEB-INF/"); 
    ... 
} 

我知道FacesContext只在请求中有效。还有其他一些窍门吗?

+3

我希望你不要在你的EJB类中使用'FacesContext'。 –

+0

我在我的资源中有一些xml文档,我想在EJB服务类中使用它。我不想在我的应用程序中对文件名进行硬编码。所以我想知道如何以编程方式查询这些名称(不使用'FacesContext')。 – Tomestos

回答

1

公约说,在三层软件架构一层只能访问底层,但没有覆层(第二天底层中严格三层架构,所有底层在灵活三层建筑)。我唯一的例外是Observer Pattern:主题通知所有附属的观察者何时数据已被更改。这是由弱参考从主体层到观察者层进行的。

我对这个问题的解决方案是,我写了一个应用程序阶段监听器(当然是在UI层),它在应用程序启动时扫描资源文件夹WEB-INF。这是合法的,因为应用程序阶段侦听器在面上下文中运行。

直到JSF 2.1为止,相位监听器都不是注入目标(请参阅here in stackoverflow)。所以有必要通过JNDI获取我的EJB引用。 EJB(位于模型层)然后自动实例化。

应用阶段监听器:

@Override 
public void processEvent(SystemEvent e) { 
    if(e instanceof PostConstructApplicationEvent) { 
    try { 
     // getting ejb by jndi 
     InitialContext iCtx = new InitialContext(); 
     EjbService ejbService = (EjbService) iCtx.lookup("java:module/EjbService"); 

     // fetching resources 
     ExternalContext eCtx = FacesContext.getCurrentInstance().getExternalContext(); 
     Set<String> resources = eCtx.getResourcePaths("/WEB-INF/"); 

     // setting resources into ejb 
     ejbService.setResources(resources); 
    } catch(NamingException e1) { 
     e1.printStackTrace(); 
    } 
    } 
} 

非常感谢所有谁在回答我的问题有帮助。

+0

您可能不希望在该方法中使用您的'EJBService'。这意味着服务查找完成*每次*方法被调用,这是有点浪费和不必要的IMO – kolossus

+0

JNDI查找很昂贵,但我认为这里没问题,因为事件类型“PostConstructApplicationEvent”在应用程序中只触发一次启动时间。 – Tomestos

相关问题