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


当前回答

假设你的代码正在寻找文件app.properties。通过在tomcat的bin目录中创建setenv.sh,将该文件复制到任何目录并将该目录添加到类路径。

在tomcat的setenv.sh中(如果这个文件不存在,创建一个,tomcat会加载这个setenv.sh文件。 # !/bin/sh 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

其他回答

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

您可以使用您的源文件夹,这样每当您构建时,这些文件都会自动复制到classes目录。

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

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

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

这是你的选择。在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。属性应该被放在webapp默认类路径覆盖的根目录中,例如webapp的/WEB-INF/lib和/WEB-INF/classes,服务器的/lib,或JDK/JRE的/lib。如果属性文件是特定于webapp的,最好将其放在/WEB-INF/classes中。如果您正在IDE中开发标准WAR项目,请将其放到src文件夹(项目的源文件夹)中。如果您正在使用Maven项目,请将其放到/main/resources文件夹中。

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

如果你放置了foo。在像com这样的Java包结构中设置它的属性。示例,然后您需要按如下方式加载它

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");
// ...

However, the visibility of the properties file depends then on the class loader in question. It's only visible to the same class loader as the one which loaded the class. So, if the class is loaded by e.g. server common classloader instead of webapp classloader, and the properties file is inside webapp itself, then it's invisible. The context class loader is your safest bet so you can place the properties file "everywhere" in the classpath and/or you intend to be able to override a server-provided one from the webapp on.


2. 把它放在webcontent中

因此,你可以通过ServletContext#getResourceAsStream()加载它与一个webcontent-relative路径:

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

注意,我已经演示了将文件放在/WEB-INF文件夹中,否则任何web浏览器都可以公开访问它。还要注意,ServletContext位于任何HttpServlet类中,只能由继承的GenericServlet#getServletContext()访问,并且位于Filter by FilterConfig#getServletContext()中。如果您不在servlet类中,它通常只是通过@Inject可注入的。


3.把它放在本地磁盘文件系统中

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

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

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


选择哪一个?

根据您自己对可维护性的看法来权衡利弊。

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

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

If you prefer being able to edit properties files programmatically from inside the web application using Properties#store() method, put it outside the web application. As the Properties#store() requires a Writer, you can't go around using a disk file system path. That path can in turn be passed to the web application as a VM argument or system property. As a precaution, never use getRealPath(). All changes in deploy folder will get lost on a redeploy for the simple reason that the changes are not reflected back in original WAR file.

参见:

getResourceAsStream() vs FileInputStream 将目录添加到tomcat类路径 以编程方式访问JSF应用程序中的属性文件

假设你的代码正在寻找文件app.properties。通过在tomcat的bin目录中创建setenv.sh,将该文件复制到任何目录并将该目录添加到类路径。

在tomcat的setenv.sh中(如果这个文件不存在,创建一个,tomcat会加载这个setenv.sh文件。 # !/bin/sh 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

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

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

我想过把我的confs放在POJO src文件夹中,但这些confs都是WEB-INF/lib文件夹中的第三方库(如Quartz或URLRewrite),所以这没有意义。我计划测试把它放在web项目“src”文件夹,当我得到它,但该文件夹目前是空的,有conf文件在它似乎不优雅。

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