使用ServletContext从外部战争中读取Hibernate属性

时间:2012-04-03 14:34:48

标签: java hibernate java-ee

首先,为重复一个常见问题的变化而道歉。但是,我很难理解这里最好的方法。我有一个使用Hibernate和Glassfish 3的应用程序。和其他人一样,我希望能够从war文件外部加载Hibernate属性。我设法开始工作的唯一解决方案如下。它从domains / domain1 / config文件夹加载属性。

private Properties getLocalHibernateProperties() {
  Properties properties = new Properties();
  try {
    File pf = new File(System.getProperty("user.dir"), PROPERTIES_FILE_NAME);
    InputStream inStream = new FileInputStream(pf);
    properties.load(inStream);
  }
  catch (Exception e) {
    e.printStackTrace();
  }     
  return properties;
} 

但是,我还发现了使用ServletContext的示例How to read properties file placed outside war?。结合各个部分:

in web.xml <listener-class>foo.bar.startup.HibernatePropertiesLoader</listener-class>

public class HibernatePropertiesLoader implements ServletContextListener {
    public void contextInitialized(ServletContextEvent event){
        ServletContext context = event.getServletContext();
        context.setAttribute("settings", new HibernatePropertiesReader(context));
    }
    public void contextDestroyed(ServletContextEvent event){}
}

public class HibernatePropertiesReader {
  ServletContext ctx = null;

  public HibernatePropertiesReader(ServletContext ctx) {
    this.ctx = ctx;
  }

  public Properties getLocalHibernateProperties() {
    Properties properties = new Properties();
    try {
      InputStream inStream = ctx.getResourceAsStream(PROPERTIES_FILE);
      properties.load(inStream);
    }
    catch (Exception e) {
      e.printStackTrace();
      }     
    return properties;
    }
}

我可以理解第二个解决方案将搜索Servlet的CLASSPATH - (这是正确的吗?)因此比我原来的解决方案更灵活。但是,我不明白如何使用(访问)HibernateUtils类中的属性。我想这意味着我对ServletContext的理解中存在一些基本缺失......

任何帮助,建议,更好的解决方案... ...

1 个答案:

答案 0 :(得分:2)

ServletContext.getResourceAsStream通常用于从Web应用程序本身加载文件。例如,如果将属性文件放在:

<CONTAINER_ROOT>/webapps/<CONTEXT>/WEB-INF/conf/hibernate.properties

然后您可以使用

加载文件
ctx.getResourceAsStream("/WEB-INF/conf/hibernate.properties");

该方法也可用于从jar文件加载“资源”,但第一种方法可能更适合获取配置文件。在这种情况下,JavaDocs非常有用。

== UPDATE ==

我现在看到你的问题是,如何从servlet上下文和Hibernate配置中获取属性对象。这取决于您的应用程序布局是什么样的。你在使用Spring吗?

假设你是,一个快速而肮脏的解决方案是让HibernateUitl实现ServletContextAware接口(假设HibernateUtil是由Spring构造的)并且具有如下代码

public class HibernateUtil implements ServletContextAware {

private ServletContext servletContext;

...

public void setServletContext(ServletContext servletContext) {
    this.servletContext = servletContext;
}

private Properties getProperties() {
  return servletContext.getAttribute("settings").getLocalHibernateProperties();  
}

...

}

这会将HibernateUtil与Servlet API结合起来,这可能是不可取的。一个稍微清洁的解决方案可能是创建一个HibernatePropertiesSource接口,然后有一个ServletContextHibernatePropertiesSource实现,它具有上述方法并将其注入HibernateUtil。

同样,这是假设您使用的是Spring。