Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将配置值传递给servlet而不在.war文件中硬编码?_Java_Eclipse_Tomcat_Servlets - Fatal编程技术网

Java 将配置值传递给servlet而不在.war文件中硬编码?

Java 将配置值传递给servlet而不在.war文件中硬编码?,java,eclipse,tomcat,servlets,Java,Eclipse,Tomcat,Servlets,我正在使用Eclipse和Tomcat6用Java开发一个Web应用程序 我需要向servlet传递一个未硬编码到.war文件中的值。 例如,假设我的servlet需要一个文件名,而该文件名在每台服务器上都是不同的。 如何将其传递给servlet,而不在.war文件中硬编码 请帮助我了解如何执行此操作的说明: 从Eclipse内部(例如:将xxxx添加到文件yyy,然后运行) 在我将在其上部署应用程序的服务器上 我正朝着getInitParameter的方向思考,但除了.war文件中的w

我正在使用Eclipse和Tomcat6用Java开发一个Web应用程序

我需要向servlet传递一个未硬编码到.war文件中的值。
例如,假设我的servlet需要一个文件名,而该文件名在每台服务器上都是不同的。
如何将其传递给servlet,而不在.war文件中硬编码

请帮助我了解如何执行此操作的说明:

  • 从Eclipse内部(例如:将xxxx添加到文件yyy,然后运行)
  • 在我将在其上部署应用程序的服务器上
我正朝着
getInitParameter
的方向思考,但除了.war文件中的
web.xml
之外,我还没有找到传递init参数的方法,因为它需要可配置,所以这不是一个选项。如果你能告诉我如何在外部文件中设置init参数,问题就解决了


注意:我正在寻找非常准确的建议,如“在该位置编辑该文件”。我已经找到了许多相关的问题和答案,但没有一个是足够具体的,可以让它工作。

在servlet代码中,您可以从驻留在类路径中的属性文件加载它,如下所示

    Properties props = new Properties();
    try {
        props.load(this.getClass().getClassLoader().getResourceAsStream("config.properties"));
    } catch (IOException e1) {
        log.error(e1.getMessage(), e1);
    }
    String prop1 = props.getProperty("prop1");

如果配置的位置已知,则可以将其作为servlet参数传递。在
web.xml
中声明servlet(我将configFile称为您希望获得引用的文件):

容器将使用
ServletConfig
调用此方法,从中可以获得对配置文件的引用。 这意味着,您根本不需要在eclipse中拥有该文件。使用这种方法,您不必在服务器上执行任何特殊操作,唯一需要注意的是文件被复制,并且您在
web.xml
上声明的路径是正确的

如果可以动态构造文件的位置,则可以使用ServletContext.getRealPath(“/”)返回webapp的绝对路径

---更新---

更新问题的答案。我不知道什么是最好的做法,但有一个变通办法。您可以在tomcat主目录中创建一个文件(
conf_location.txt
),其中包含一行您希望传递给servlet的文件的位置。在您的servlet中,您可以使用此黑客访问该文件(假设您的war位于
$TOMCAT_HOME/webapps/mywar.war
):


有很多方法可以做到这一点。这实际上取决于您在什么时候知道要加载的文件的位置。如果您要为每个tomcat实例/服务器配置它,那么环境变量或JVM参数可能是最简单的。然后可以通过代码中的System.getProperty查找此变量

您可以通过CATALINA_HOME/bin/setenv.sh在每个tomcat的基础上传递JVM参数

#!/bin/sh
CATALINA_OPTS="$CATALINA_OPTS
    -Dmy.file.path=/path/on/this/host/file.txt"
在您的代码中:

String path = System.getProperty("my.file.path")
达努什的建议也是一个很好的建议,从长远来看可能更具可持续性。它的优点是将每个环境的所有配置保存在一个可以保存在源代码管理中的位置。然而,使用他的方法,您仍然需要一种从属性文件中选择适当密钥的方法(因为这个属性文件将捆绑在您的war中),您可以再次使用环境变量或JVM参数来控制它

如果你想变得稍微花哨一点,你可以考虑使用

  • 对于真正的项目,您不应该直接使用servlet。使用一个有助于引导你前进的框架。春天很常见
  • 如果您使用Spring,在您的应用程序上下文中将有一个称为属性占位符配置器的bean。请参见示例:。最好的做法是硬编码该文件位置(或者
    文件:
    或者
    类路径:
    ),但将其放在WAR文件之外
  • application-context.xml:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config/properties/database.properties</value>
            </list>
        </property>
        <property name="ignoreResourceNotFound" value="true"/>
    </bean>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    
    
    类路径:config/properties/database.properties
    
  • 在需要配置文件的代码中加载配置文件时存在几个设计问题。它使测试变得困难,使一般设计变得不那么灵活,如果明天您认为属性文件不足,并且希望将配置存储在ZooKeeper或JNDI中,那么您必须重写大量代码。将代码编写为注入设置的对象,并按照上面的
    dataSource
    模式实例化它们

  • 别忘了在你的tomcat上添加一个扩展目录。您可以查看conf/catalina.properties文件中的属性'shared.loader',我到底需要将“config.properties”放在哪里?有必要把它放在一个外部文件夹中吗?Tomcat/Lib目录是一个我在Eclipse中看不到Tomcat/Lib文件夹的地方。在哪里可以找到它?@PlínioPantaleão我添加了config.properties的路径,但这不起作用。(我在源代码中使用了
    /config.properties
    ),但是
    web.xml
    不是
    .war
    文件的一部分吗?因为这就是我声明servlet的地方。我确实喜欢
    init param
    方式,但我希望能够在
    .war
    之外设置它。这可能吗?我应该把它放在哪里?但是您的servlet需要知道使用/解析什么。只需将引用传递给文件,而不是文件本身。如果还想包含该文件,可以将其放在“webapp/WEB-INF/classes”中,并从servlet中解析为下面描述的“Dhanush Gopinath”。不过,我可能误解了这个问题。传递引用是可以的,但是我如何做到这一点(不在.war文件中硬编码该引用)?我已经在问题中澄清了这一点。基本上,我事先什么都不知道。在服务器A上,我希望能够传递“/data/myfile.txt”,在服务器B上,我希望传递“/home/user/files/ot”
    #!/bin/sh
    CATALINA_OPTS="$CATALINA_OPTS
        -Dmy.file.path=/path/on/this/host/file.txt"
    
    String path = System.getProperty("my.file.path")
    
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config/properties/database.properties</value>
            </list>
        </property>
        <property name="ignoreResourceNotFound" value="true"/>
    </bean>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>