Java 使用ServletContext从war外部读取Hibernate属性
首先,为重复一个经常被问到的问题而道歉。然而,我正在努力理解这里的最佳方法。我有一个使用Hibernate和Glassfish 3的应用程序。和其他人一样,我希望能够从war文件外部加载Hibernate属性。我成功地开始工作的唯一解决方案如下。它从domains/domain1/config文件夹加载属性Java 使用ServletContext从war外部读取Hibernate属性,java,hibernate,jakarta-ee,Java,Hibernate,Jakarta Ee,首先,为重复一个经常被问到的问题而道歉。然而,我正在努力理解这里的最佳方法。我有一个使用Hibernate和Glassfish 3的应用程序。和其他人一样,我希望能够从war文件外部加载Hibernate属性。我成功地开始工作的唯一解决方案如下。它从domains/domain1/config文件夹加载属性 private Properties getLocalHibernateProperties() { Properties properties = new Properties();
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的示例。结合各部分:
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;
}
}
web.xml foo.bar.startup.HibernatePropertiesLoader中的
公共类HibernatePropertiesLoader实现ServletContextListener{
公共void contextInitialized(ServletContextEvent事件){
ServletContext=event.getServletContext();
setAttribute(“设置”,新的HibernatePropertiesReader(context));
}
public void contextdestromed(ServletContextEvent事件){}
}
公共类HibernatePropertiesReader{
ServletContext ctx=null;
公共HibernatePropertiesReader(ServletContext ctx){
this.ctx=ctx;
}
公共属性getLocalHibernateProperties(){
属性=新属性();
试一试{
InputStream inStream=ctx.getResourceAsStream(属性文件);
特性。负载(流内);
}
捕获(例外e){
e、 printStackTrace();
}
归还财产;
}
}
我可以理解,第二个解决方案将搜索Servlet的类路径-(是否正确?),因此比我的原始解决方案更灵活。但是,我不明白如何使用(访问)HibernateUtils类中的属性。我想这意味着我对ServletContext的理解中缺少了一些基本的东西
感谢任何帮助、建议和更好的解决方案……ServletContext.getResourceAsStream通常用于从web应用程序本身加载文件。例如,如果将属性文件放置为:
<CONTAINER_ROOT>/webapps/<CONTEXT>/WEB-INF/conf/hibernate.properties
该方法也可用于从jar文件加载“资源”,但第一种方法可能更适合获取配置文件。在这种情况下,这些方法非常有用
==更新==
我发现您现在的问题是,如何将properties对象从servlet上下文中取出并放入Hibernate配置中。这取决于应用程序的布局。你在用弹簧吗
假设您是,一个快速而肮脏的解决方案是让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与ServletAPI耦合,这可能是不可取的。稍微干净一点的解决方案可能是创建一个HibernatePropertiesSource接口,然后有一个ServletContextHibernatePropertiesSource实现,该实现具有上述方法,并将其注入HibernateUtil
同样,这都是假设您使用的是Spring。那么,ServletContext并不适合从应用程序外部加载“特定于安装”的属性?我突然意识到第一个解决方案可能没有那么灵活-也许我在这里错了。将特定于安装的属性放在上下文根中有什么问题?您是否建议将它们放在用户的主目录中?一个用户可以在不同的端口上运行同一应用程序的多个实例。我想我正在尝试解决一个问题,即需要升级站点的WAR而不替换本地配置数据。我说的在上下文中根实际上在未打包的战争中是正确的吗?是的,你是正确的。我现在明白你的意思了。我将更新我的答案。我目前没有使用Spring(也许我应该这么做!),但这似乎是一个很好的方法。我将调查将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();
}
...
}