使用Servlet上下文从外部读取Hibernate属性



首先,很抱歉重复了一个常见问题的变体。然而,我很难理解这里的最佳方法。我有一个使用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;
} 

然而,我也发现并举例说明了如何读取放置在战争之外的属性文件?使用Servlet上下文。组合各个部分:

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(这是正确的吗?),因此比我的原始解决方案更灵活。但是,我不知道如何使用(访问)Hibernate Utils类中的属性。我想这意味着在我对ServletContext的理解中有一些根本性的缺失。。。。

感谢任何帮助、建议和更好的解决方案。。。

ServletContext.getResourceAsStream通常用于从web应用程序本身加载文件。例如,如果您将属性文件放置为:
<CONTAINER_ROOT>/webapps/<CONTEXT>/WEB-INF/conf/hibernate.properties

然后你可以使用加载文件

ctx.getResourceAsStream("/WEB-INF/conf/hibernate.properties");

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

===更新===

我现在看到的问题是,如何将properties对象从servlet上下文中取出并放入Hibernate配置中。这取决于您的应用程序布局。你在用弹簧吗?

假设你是这样的,一个快速而肮脏的解决方案是让Hibernate Uitl实现ServletContextAware接口(假设Hibernate Util是由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接口,然后有一个具有上述方法的Servlet上下文HibernatePropertiesSource实现,并将其注入HibernateUtil。

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

最新更新