Servlets 在基于servlet的应用程序中,在何处放置和如何读取配置资源文件?

Servlets 在基于servlet的应用程序中,在何处放置和如何读取配置资源文件?,servlets,jakarta-ee,configuration,resources,properties-file,Servlets,Jakarta Ee,Configuration,Resources,Properties File,在我的web应用程序中,我必须向一组预定义的用户发送电子邮件,如finance@xyz.com,因此我希望将其添加到.properties文件中,并在需要时访问它。这是一个正确的程序吗?如果是,那么我应该把这个文件放在哪里?我使用的是Netbeans IDE,它有两个单独的文件夹来存放源文件和JSP文件。它只需要位于类路径中(也就是说,确保它作为构建的一部分最终位于.war中的/WEB-INF/classes下)。您可以使用源文件夹,这样无论何时构建,这些文件都会自动复制到classes目录中

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

它只需要位于类路径中(也就是说,确保它作为构建的一部分最终位于.war中的/WEB-INF/classes下)。

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

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

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


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

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


1.把它放在类路径中 因此,您可以使用类路径相对路径加载它:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
这里的
foo.properties
应该放在webapp默认类路径覆盖的根目录中,例如webapp的
/WEB-INF/lib
/WEB-INF/classes
、服务器的
/lib
或JDK/JRE的
/lib
。如果属性文件特定于webapp,最好将其放置在
/WEB-INF/classes
中。如果您正在IDE中开发标准WAR项目,请将其放入
src
文件夹(项目的源文件夹)。如果您使用的是Maven项目,请将其放入
/main/resources
文件夹中

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

如果您已将
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.把它放在webcontent中 因此,您可以使用webcontent相对路径加载它:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
请注意,我已经演示了如何将文件放在
/WEB-INF
文件夹中,否则任何webbrowser都可以公开访问该文件。还请注意,
ServletContext
位于继承的可访问的任何
HttpServlet
类中,而
Filter
则位于继承的可访问的类中。如果您不在servlet类中,它通常只是通过
@Inject
注入的


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

InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
请注意使用绝对路径的重要性。相对本地磁盘文件系统路径在JavaEEWeb应用程序中是绝对不允许的。另请参见下面的第一个“请参见”链接


选择哪一个? 只需根据您自己对可维护性的看法权衡利弊即可

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

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

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

另见:

Ex:在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>

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

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

我曾考虑将我的conf放在POJO src文件夹中,但这些conf都是针对
WEB-INF/lib
文件夹中的第三方lib(如Quartz或URLRewrite),因此没有意义。我计划在开始使用它时,将它放在WebProjects的“src”文件夹中进行测试,但该文件夹目前是空的,其中包含conf文件似乎不美观

所以我投票赞成将conf文件放在
WEB-INF/commonConfFolder/filename.pr中