228

在我的 Web 应用程序中,我必须向一组预定义的用户发送电子邮件,例如finance@xyz.com,所以我希望将其添加到.properties文件中并在需要时访问它。这是一个正确的程序,如果是,那么我应该把这个文件放在哪里?我正在使用 Netbeans IDE,它有两个单独的文件夹用于源文件和 JSP 文件。

4

6 回答 6

474

这是你的选择。Java Web 应用程序归档 (WAR) 中基本上有三种方式:


1.放在类路径中

这样您就可以ClassLoader#getResourceAsStream()使用类路径相对路径加载它:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

这里foo.properties应该放置在 webapp 的默认类路径所涵盖的根目录之一中,例如 webapp's /WEB-INF/liband /WEB-INF/classes、 server's/lib或 JDK/JRE's /lib。如果属性文件是特定于 webapp 的,最好将它放在/WEB-INF/classes. 如果您在 IDE 中开发标准 WAR 项目,请将其放入src文件夹(项目的源文件夹)中。如果您使用的是 Maven 项目,请将其放入/main/resources文件夹中。

您也可以将其放在默认类路径之外的某个位置,并将其路径添加到应用服务器的类路径中。例如在 Tomcat 中,您可以将其配置shared.loaderTomcat/conf/catalina.properties.

如果您已将foo.properties它放在 Java 包结构com.example中,则需要按如下方式加载它

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...

请注意,上下文类加载器的此路径不应以/. 仅当您使用“相对”类加载器(例如 )时SomeClass.class.getClassLoader(),您确实需要以/.

ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...

但是,属性文件的可见性取决于相关的类加载器。它只对与加载该类的类加载器相同的类加载器可见。因此,如果类是由例如服务器公共类加载器而不是 webapp 类加载器加载的,并且属性文件在 webapp 本身内部,那么它是不可见的。上下文类加载器是您最安全的选择,因此您可以将属性文件“无处不在”放在类路径中和/或您打算能够从 webapp 覆盖服务器提供的文件。


2. 放入网页内容

这样您就可以ServletContext#getResourceAsStream()使用 webcontent-relative 路径加载它:

InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...

请注意,我已经演示了将文件放在/WEB-INF文件夹中,否则任何网络浏览器都可以公开访问它。另请注意,ServletContext在任何HttpServlet类中,都只能由继承的GenericServlet#getServletContext()和 inFilter访问FilterConfig#getServletContext()。如果您不在 servlet 类中,通常可以通过@Inject.


3.放入本地磁盘文件系统

这样您就可以java.io使用绝对本地磁盘文件系统路径以通常的方式加载它:

InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...

请注意使用绝对路径的重要性。相对本地磁盘文件系统路径在 Java EE Web 应用程序中是绝对不允许的。另请参阅下面的第一个“另请参阅”链接。


选择哪个?

只需权衡您自己对可维护性的看法的优点/缺点。

如果属性文件是“静态的”并且在运行时不需要更改,那么您可以将它们保留在 WAR 中。

如果您希望能够从 Web 应用程序外部编辑属性文件,而无需每次都重新构建和重新部署 WAR,则将其放在项目外部的类路径中(如有必要,将目录添加到类路径中)。

如果您希望能够使用Properties#store()方法从 Web 应用程序内部以编程方式编辑属性文件,请将其放在 Web 应用程序之外。由于Properties#store()需要 a Writer,您不能使用磁盘文件系统路径。该路径又可以作为 VM 参数或系统属性传递给 Web 应用程序。作为预防措施,切勿使用getRealPath(). 部署文件夹中的所有更改都将在重新部署时丢失,原因很简单,更改不会反映在原始 WAR 文件中。

也可以看看:

于 2010-01-29T11:36:17.023 回答
10

警告语:如果您将配置文件放在您的WEB-INF/classes文件夹中,并且您的 IDE(例如 Eclipse)执行清理/重建,它将删除您的 conf 文件,除非它们位于 Java 源目录中。BalusC 的好答案在选项 1 中暗示了这一点,但我想强调一下。

我了解到,如果您在 Eclipse 中“复制”一个 Web 项目,它会从任何源文件夹进行清理/重建。在我的例子中,我从我们的 POJO java 库中添加了一个“链接源目录”,它将编译到该WEB-INF/classes文件夹​​中。在该项目(不是 Web 应用程序项目)中进行清理/重建会导致同样的问题。

我曾考虑将我的 conf 文件放在 POJO src 文件夹中,但这些 conf 文件都是用于文件夹中的第 3 方库(如 Quartz 或 URLRewrite)WEB-INF/lib,所以这没有意义。当我开始使用它时,我计划测试将它放入 web 项目的“src”文件夹中,但该文件夹目前是空的,并且其中包含 conf 文件似乎不优雅。

所以我投票赞成将 conf 文件放在classes 文件夹旁边WEB-INF/commonConfFolder/filename.properties,这是 Balus 选项 2。

于 2014-06-19T16:08:09.657 回答
6

例如:在 web.xml 文件中的标签

<context-param>
        <param-name>chatpropertyfile</param-name>
        <!--  Name of the chat properties file. It contains the name and description                   of rooms.-->     
        <param-value>chat.properties</param-value>
    </context-param>

并且 chat.properties 你可以像这样声明你的属性

例如:

Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.
于 2012-08-15T08:08:20.700 回答
5

它只需要在类路径中(也就是确保它作为构建的一部分在 .war 中的 /WEB-INF/classes 下结束)。

于 2010-01-29T09:47:43.823 回答
3

您可以使用源文件夹,因此无论何时构建,这些文件都会自动复制到类目录中。

不要使用属性文件,而是使用 XML 文件。

如果数据太小,您甚至可以使用 web.xml 来访问属性。

请注意,这些方法中的任何一种都需要重新启动应用服务器才能反映更改。

于 2010-01-29T09:53:55.177 回答
2

假设您的代码正在寻找 app.properties 文件。将此文件复制到任何目录并将此目录添加到类路径中,方法是在 tomcat 的 bin 目录中创建一个 setenv.sh。

在你的tomcat的setenv.sh中(如果这个文件不存在,创建一个,tomcat会加载这个setenv.sh文件。 #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

你不应该在 ./webapps//WEB-INF/classes/app.properties 中有你的属性文件

Tomcat 类加载器将覆盖 WEB-INF/classes/ 中的类加载器

一个很好的阅读: https ://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

于 2018-10-04T19:36:52.947 回答