Java 如何读取放置在war之外的属性文件?

Java 如何读取放置在war之外的属性文件?,java,web-applications,jakarta-ee,properties,Java,Web Applications,Jakarta Ee,Properties,这些天我在做一个网络应用程序。它只使用JSP和servlet。这是一个小应用程序。现在,我已经将所有数据源细节放在DAO实用程序类中。我想把这些细节放在一个可以放在war之外的属性文件中,这样我们就可以根据环境来更改这些值,而不会影响war。如何实现这一点?使用上下文参数或java系统参数提供文件名 1.上下文参数 <context-param> <param-name>daofilename</param-name> <param-value>D

这些天我在做一个网络应用程序。它只使用JSP和servlet。这是一个小应用程序。现在,我已经将所有数据源细节放在DAO实用程序类中。我想把这些细节放在一个可以放在war之外的属性文件中,这样我们就可以根据环境来更改这些值,而不会影响war。如何实现这一点?

使用上下文参数或java系统参数提供文件名

1.上下文参数

<context-param>
<param-name>daofilename</param-name>
<param-value>D:\daofilename.props</param-value>
</context-param>

您应该将属性文件位置作为java运行时属性指定给web容器

比如,,
java-DmypropertyFile.location=c:/propertyfile.properties-jar yourContainer.jar

如果您使用的是Tomcat,您可以向上下文添加任何您喜欢的属性,请查看。所有的应用服务器都有自己的方法来实现这一点,因此您必须在JBoss、Glassfish等中寻找实现这一点的示例


另一个更难但可能更好的解决方案是使用。

我通常采用的方法是让程序假定配置文件位于
%user.home%/.program/config.properties

如果找不到该文件(通常在第一次运行时),将从“默认”配置文件的类路径创建一个副本并放置在那里


为了灵活性,通常可以使用-Dconfig=somepath覆盖该属性。

根据您的web服务器,您可以将属性文件放置在类路径中包含的某个位置。例如,对于某些tomcat版本,这将是
${tomcat_BASE}/shared/classes
。然后,webapp可以使用类似以下内容的内容来读取文件,并在该位置自动找到该文件

ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream("yourfilename.cnf");
您还可以使用webapp的安装名称命名文件,并在从类路径加载文件时在代码中使用该名称。这样,您就可以在共享目录中拥有多个webapp的属性文件,而不会相互冲突

您已经指出您没有访问ServletContext的权限,因为您希望代码位于实用程序类中。可以绕过此限制的一种方法是注册一个ServletContextListener,它创建属性文件读取器的实例(因为它可以访问上下文)并注册它,以便其他代码可以使用它。如下所示:

public class MyServletContextListener extends ServletContextListener{
    public void contextInitialized(ServletContextEvent event){
        ServletContext context = event.getServletContext();
        context.setAttribute("settings", new MyPropertyReader(context));
    }

    public void contextDestroyed(ServletContextEvent event){}
    }

}
我就是这样做的:

将以下内容添加到context.xml文件(conf文件夹,位于tomcat安装目录中)。您可以更改名称属性;并在值中设置包含属性文件的文件夹的路径

<Environment name="config" value="C:\Program files\my app\"  
         type="java.lang.String" override="false"/>

希望这对您或其他人有所帮助。

但是,属性文件位置取决于战争。您应该更改war文件以更改属性文件位置。如果我正确,则要求更改文件中的属性,而不是文件本身。@Gursel Koca如果是这样,即使系统参数也要求更改运行脚本文件中的属性,则我必须修改属性文件中的属性。要将属性文件放置在相对于WAR的路径上。我无法访问dev和prod框。另外,我不想在Servlet级别读取属性文件,我想在负责提供数据源的实用程序类中读取它。ServletContext和所有内容仅在servlet级别可用。更新了我的答案以回应您的评论。这个答案对我帮助很大。各位,别忘了关闭输入流。
<Environment name="config" value="C:\Program files\my app\"  
         type="java.lang.String" override="false"/>
String folderName = null;
Properties properties = new Properties();
try {
   InitialContext context = new InitialContext();
   folderName = (String) context.lookup("java:comp/env/config");
} catch (NamingException ex) {
   System.out.println("exception in jndi lookup");
}
if(folderName != null) {
   File configFile = new File(folderName + "yourfile.properties");
   try {
       InputStream is = new FileInputStream(configFile);
       properties.load(is);
   } catch(IOException ex) {
      System.out.println("exception loading properties file");
   }
}