【问题标题】:How to get Resource Paths without FacesContext?如何在没有 FacesContext 的情况下获取资源路径?
【发布时间】:2013-07-03 14:12:57
【问题描述】:

我正在尝试使用 ExternalContext 中的方法 getResourcePaths() 来获取 WAR 文件中的资源路径。但是如果方法被@Schedule调用怎么办呢?在这种情况下,FacesContext 为空。

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

我知道 FacesContext 仅在请求中有效。是不是还有什么妙招?

【问题讨论】:

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

标签: java jsf web-applications jsf-2


【解决方案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();
    }
  }
}

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

【讨论】:

  • 您可能不想在该方法中使用您的EJBService。这意味着每次方法调用都会进行服务查找,这有点浪费和不必要的IMO
  • JNDI 查找代价高昂,但我认为这里没问题,因为事件类型PostConstructApplicationEvent 仅在应用程序启动时触发一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-15
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多