在我的 Web 应用程序中,我必须向一组预定义的用户发送电子邮件,例如finance@xyz.com
,所以我希望将其添加到.properties
文件中并在需要时访问它。这是一个正确的程序,如果是,那么我应该把这个文件放在哪里?我正在使用 Netbeans IDE,它有两个单独的文件夹用于源文件和 JSP 文件。
6 回答
这是你的选择。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/lib
and /WEB-INF/classes
、 server's/lib
或 JDK/JRE's /lib
。如果属性文件是特定于 webapp 的,最好将它放在/WEB-INF/classes
. 如果您在 IDE 中开发标准 WAR 项目,请将其放入src
文件夹(项目的源文件夹)中。如果您使用的是 Maven 项目,请将其放入/main/resources
文件夹中。
您也可以将其放在默认类路径之外的某个位置,并将其路径添加到应用服务器的类路径中。例如在 Tomcat 中,您可以将其配置shared.loader
为Tomcat/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 文件中。
也可以看看:
警告语:如果您将配置文件放在您的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。
例如:在 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.
它只需要在类路径中(也就是确保它作为构建的一部分在 .war 中的 /WEB-INF/classes 下结束)。
您可以使用源文件夹,因此无论何时构建,这些文件都会自动复制到类目录中。
不要使用属性文件,而是使用 XML 文件。
如果数据太小,您甚至可以使用 web.xml 来访问属性。
请注意,这些方法中的任何一种都需要重新启动应用服务器才能反映更改。
假设您的代码正在寻找 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