小编典典

在基于 servlet 的应用程序中放置以及如何读取配置资源文件?

all

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


阅读 87

收藏
2022-06-08

共1个答案

小编典典

这是你的选择。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 文件中。

2022-06-08