【问题标题】:Is it possible to access database.properties file from outside of project structure in Hibernate?是否可以从 Hibernate 的项目结构外部访问 database.properties 文件?
【发布时间】:2016-05-12 10:07:42
【问题描述】:

我正在尝试使用项目外部的 database.properties 文件设置休眠项目的配置。尝试在 web.xml 中设置如下

<context-param>
        <param-name>propertiesLocation</param-name>
        <param-value>classpath:resources/database.properties</param-value>
    </context-param> 

在 sdnext-servlet.xml 中

<context:property-placeholder location="file:${#{contextParameters.propertiesLocation}" /> <br><br>

但未能达到所需的输出。 以上配置仍然强制将属性文件放入项目结构中可以做些什么以便在项目之外访问它?

以下配置适用于项目中的 database.properties 文件。 &lt;context:property-placeholder location="classpath:resources/database.properties"/&gt;

需要进行哪些更改,以便项目可以访问项目外部的 database.properties 文件。

web.xml 文件是

<servlet>
        <servlet-name>sdnext</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/sdnext-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>sdnext</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

sdnext-servlet.xml 是

<context:property-placeholder location="classpath:resources/database.properties"/>
    <context:component-scan base-package="com.dineshonjava" />
    <tx:annotation-driven transaction-manager="hibernateTransactionManager" />

    <bean id="jspViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.dineshonjava.model.Employee</value>
                <value>com.dineshonjava.model.Books</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

【问题讨论】:

  • 您是否尝试在location 中提供属性文件的绝对路径?
  • @ user2004685 是的,我试过这样 所以它工作正常。但我正在尝试这样做,以便它不应该在任何一个文件中硬编码。有可能吗?
  • file:${#{contextParameters.propertiesLocation} 在这里你没有结束}。是不是打错字了?
  • @ user2004685 是的,这只是这里的编辑错误。当我使用上面的配置得到这个: java.io.FileNotFoundException: ${ (No such file or directory)
  • 占位符不起作用,您可以尝试#{environment['propertiesLocation']}。

标签: java xml spring hibernate servlets


【解决方案1】:

我在file:${#{contextParameters.propertiesLocation} 中看到一个错字,您没有以} 结束该属性。

试试这个:

&lt;context:property-placeholder location="file:#{contextParameters.propertiesLocation}"/&gt;

【讨论】:

  • 感谢您的回复。但这个解决方案不适用于我的情况
  • 严重:为 servlet sdnext java.io.FileNotFoundException 分配异常:/${contextParameters.propertiesLocation}(没有这样的文件或目录)
【解决方案2】:

如前所述,它与 Hibernate 或除 Spring 之外的其他框架无关。这与您对占位符(处理)和Spring EL 的误解有关。

您正在尝试使用占位符配置&lt;context:property-placeholder /&gt;。现在,您在完全解析这些占位符的基础设施实际到位之前使用占位符。

如果您真的想使用动态方式设置配置,您将不得不求助于使用 Spring EL。您实际上将不得不进行xml 编程 之类的事情。

您需要使用environment 变量从已知位置解析变量,例如系统环境、系统属性、jndi、servlet 上下文等。使用getRequiredProperty(...) 方法解析值。

<context:property-placeholder location="#{environment.getRequiredProperty('propertiesLocation')}" />

注意:这不起作用,因为location 属性不知道 EL。请改用普通的PropertySourcesPlaceholderConfigurer。

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="location" value="#{environment.getRequiredProperty('propertiesLocation')}" />
</bean>

现在您需要在某处定义名为propertiesLocation 的属性,这可以是任何一种(取决于环境和环境的可能性)。

  • 系统环境变量
  • 系统属性 (java -D)
  • Servlet 上下文参数
  • Servlet 初始化参数
  • JNDI

在您的情况下,您想使用上下文参数

<context-param>
    <param-name>propertiesLocation</param-name>
    <param-value>classpath:resources/database.properties</param-value>
</context-param>

现在不要使用classpath:resources/database.properties,而是使用file:/some/path/on/your/system/database.properties 之类的其他名称。有关支持的前缀的更多信息,请参阅resource loading 上的参考指南。

但是,您最好为此使用 JNDI 条目的系统环境变量,否则它仍然是相当静态的,您最好直接指定 location="file:/some/path/on/your/system/database.properties。

【讨论】:

  • 感谢您的努力。但是在做了你提到的所有改变之后,它仍然不适合我。
  • 什么不起作用?如果该属性不存在,您应该得到一个异常,如果它确实解析为 null 或 "" 它应该加载文件。如果发生这种情况,您的文件不包含所需的占位符。
  • java.io.FileNotFoundException: 无法打开 ServletContext 资源 [/#{environment.getRequiredProperty('propertiesLocation')}]
  • Hmm.. 显然 location 属性不支持 EL(认为它已修复)。而不是命名空间,而是直接使用PropertySourcesPlaceholderConfigurer。我会更新答案。
  • 谢谢。这个解决方案奏效了。我不得不将弹簧罐从 3.0.1 更改为 3.1.1
【解决方案3】:

按照@user2004685 的建议,如果在location 中为您的属性文件提供绝对路径有效,那么您可以通过定义包含文件路径的Maven 属性来解决硬编码 问题,在您的项目构建周期中被替换。

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 2020-03-26
    • 1970-01-01
    • 2020-09-13
    • 2018-12-25
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多