2012-04-03 66 views
1

首先,道歉重复一个常见问题的变体。但是,我正在努力理解这里的最佳方法。我有一个使用Hibernate和Glassfish 3的应用程序。与其他人一样,我希望能够从war文件外部加载Hibernate属性。我设法开展工作的唯一解决方案如下。它从domains/domain1/config文件夹加载属性。使用ServletContext读取来自外部战争的Hibernate属性

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的理解....

任何援助,咨询,更好的解决方案赞赏...

回答

2

的ServletContext.getResourceAsStream通常用来加载一个文件从网络应用程序本身。例如,如果你把你的属性文件:

<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。

+0

因此,ServletContext不适合从应用程序外部加载“特定于安装的”属性?这让我感到震惊,第一个解决方案可能不够灵活 - 也许我错了。 – skyman 2012-04-03 15:00:11

+0

将上下文根目录中的特定安装属性置于什么位置?你是否建议将它们放在用户的主目录中?单个用户可以在不同的端口上运行同一应用程序的多个实例。 – Pace 2012-04-04 04:17:11

+0

我想我正试图解决一个问题,我需要升级站点的WAR而不替换本地配置数据。我是否正确地说在上下文中根目录实际上是在未打包的WAR中? – skyman 2012-04-04 04:29:02