我正在尝试使用 ExternalContext 中的 getResourcePaths()方法获取WAR文件中的资源路径。但如果@Schedule
调用该方法,该如何做呢?在这种情况下,FacesContext为null。
@Schedule(hour = "*", minute = "0,30", second = "0")
public void foo() {
ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
Set<String> resources = ctx.getResourcePaths("/WEB-INF/");
...
}
我知道FacesContext仅在请求中有效。还有其他一些技巧吗?
答案 0 :(得分:1)
惯例说,在三层软件架构中,一层可能只访问底层,但没有覆盖层(严格三层架构中的下一个底层 > 灵活三层架构中的所有底层。我所知道的唯一例外是Observer Pattern:当数据发生变化时,主题会通知所有附加的观察者。这是通过主题层到观察者层的弱引用进行的。
我解决这个问题的方法是,我编写了一个Application Phase Listener(当然位于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();
}
}
}
非常感谢所有帮助回答我问题的人。