【问题标题】:Read Hibernate properties from outside war using ServletContext使用 ServletContext 从外部战争中读取 Hibernate 属性
【发布时间】:2012-04-03 14:34:48
【问题描述】:

首先,很抱歉重复了一个常见问题的变体。但是,我很难理解这里的最佳方法。我有一个使用 Hibernate 和 Glassfish 3 的应用程序。像其他人一样,我希望能够从 war 文件外部加载 Hibernate 属性。我设法开始工作的唯一解决方案如下。它从 domain/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 的理解中缺少一些基本的东西......

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

【问题讨论】:

    标签: java hibernate jakarta-ee


    【解决方案1】:

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

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

    然后你可以使用加载文件

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

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

    ==更新==

    我现在看到您的问题是,您如何将属性对象从 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。

    【讨论】:

    • 那么,ServletContext 是否真的不适合从应用程序外部加载“特定于安装”的属性?让我震惊的是,第一个解决方案可能没有那么灵活——也许我在这里错了。
    • 将安装特定的属性放在上下文根中有什么问题?您是否建议将它们放在用户的主目录中?单个用户可以在不同端口上运行同一应用程序的多个实例。
    • 我想我正在尝试解决一个问题,即我需要在不替换本地配置数据的情况下升级站点的 WAR。我是否正确地说上下文根内部实际上是在未打包的 WAR 中?
    • 是的,你是对的。我现在明白你的意思了。我会更新我的答案。
    • 我目前没有使用 Spring(也许我应该使用!),但这似乎是一个好方法。我将研究将 Spring 引入应用程序 - 以及其他目的。谢谢你的建议。
    猜你喜欢
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 2011-09-06
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多