在我的 Web 应用程序中,我必须向一组预定义的用户发送电子邮件,例如finance@xyz.com,所以我希望将其添加到.properties文件中并在需要时访问它。这是一个正确的程序,如果是,那么我应该把这个文件放在哪里?我正在使用 Netbeans IDE,它有两个单独的文件夹用于源文件和 JSP 文件。
finance@xyz.com
.properties
这是你的选择。Java Web 应用程序归档 (WAR) 中基本上有三种方式:
这样您就可以ClassLoader#getResourceAsStream()使用类路径相对路径加载它:
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文件夹中。
foo.properties
/WEB-INF/lib
/WEB-INF/classes
/lib
src
/main/resources
您也可以将它放在默认类路径之外的某个位置,并将其路径添加到应用服务器的类路径中。在例如 Tomcat 中,您可以将其配置shared.loader为Tomcat/conf/catalina.properties.
shared.loader
Tomcat/conf/catalina.properties
如果您已将foo.properties它放在 Java 包结构中,如com.example,那么您需要按如下方式加载它
com.example
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream input = classLoader.getResourceAsStream("com/example/foo.properties"); // ...
请注意,上下文类加载器的此路径不应以/. 仅当您使用“相对”类加载器(例如 )时SomeClass.class.getClassLoader(),您确实需要以/.
/
SomeClass.class.getClassLoader()
ClassLoader classLoader = getClass().getClassLoader(); InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties"); // ...
但是,属性文件的可见性取决于相关的类加载器。它只对与加载该类的类加载器相同的类加载器可见。因此,如果类是由例如服务器公共类加载器而不是 webapp 类加载器加载的,并且属性文件在 webapp 本身内部,那么它是不可见的。上下文类加载器是您最安全的选择,因此您可以将属性文件“无处不在”放在类路径中和/或您打算能够从 webapp 覆盖服务器提供的文件。
这样您就可以ServletContext#getResourceAsStream()使用 webcontent-relative 路径加载它:
ServletContext#getResourceAsStream()
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties"); // ...
请注意,我已经演示了将文件放在/WEB- INF文件夹中,否则任何网络浏览器都可以公开访问它。另请注意,ServletContext在任何HttpServlet类中,都只能由继承的GenericServlet#getServletContext()和 inFilter访问FilterConfig#getServletContext()。如果您不在 servlet 类中,通常可以通过@Inject.
/WEB- INF
ServletContext
HttpServlet
GenericServlet#getServletContext()
Filter
FilterConfig#getServletContext()
@Inject
这样您就可以java.io使用绝对本地磁盘文件系统路径以通常的方式加载它:
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 文件中。
Properties#store()
Writer
getRealPath()