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

发布于 2024-08-19 18:08:32 字数 308 浏览 7 评论 0原文

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

In my web application I have to send email to set of predefined users like [email protected], so I wish to add that to a .properties file and access it when required. Is this a correct procedure, if so then where should I place this file? I am using Netbeans IDE which is having two separate folders for source and JSP files.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

愚人国度 2024-08-26 18:08:32

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


1. 将其放入类路径中

,以便可以通过 ClassLoader#getResourceAsStream() 带有类路径相对路径:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

此处 < code>foo.properties 应该放置在 web 应用程序的默认类路径覆盖的根目录之一中,例如 web 应用程序的 /WEB-INF/lib/ WEB-INF/classes、服务器的 /lib 或 JDK/JRE 的 /lib。如果属性文件是特定于 web 应用程序的,最好将其放置在 /WEB-INF/classes 中。如果您正在 IDE 中开发标准 WAR 项目,请将其放入 src 文件夹(项目的源文件夹)中。如果您使用的是 Maven 项目,请将其放入 /main/resources 文件夹中。

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

如果您已将 foo.properties 放在像 com.example 这样的 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");
// ...

但是,属性文件的可见性取决于相关的类加载器。它仅对加载该类的同一类加载器可见。因此,如果该类是由服务器通用类加载器而不是 webapp 类加载器加载的,并且属性文件位于 webapp 本身内部,那么它是不可见的。上下文类加载器是您最安全的选择,因此您可以将属性文件放置在类路径中的“任何位置”和/或您打算能够从 Web 应用程序覆盖服务器提供的属性文件。


2.将其放入webcontent中

,以便可以通过 ServletContext#getResourceAsStream() 带有 webcontent 相对路径:

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

请注意,我已演示将文件放置在 /WEB-INF 文件夹,否则任何网络浏览器都可以公开访问它。另请注意,ServletContext 位于任何 HttpServlet 类中,只能通过继承的 GenericServlet#getServletContext() 并在 Filter 中按 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() 需要 Writer,因此您无法使用磁盘文件系统路径。该路径又可以作为 VM 参数或系统属性传递到 Web 应用程序。作为预防措施,永远不要使用getRealPath()。部署文件夹中的所有更改都将在重新部署时丢失,原因很简单,这些更改不会反映在原始 WAR 文件中。

另请参阅:

It's your choice. There are basically three ways in a Java web application archive (WAR):


1. Put it in classpath

So that you can load it by ClassLoader#getResourceAsStream() with a classpath-relative path:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

Here foo.properties is supposed to be placed in one of the roots which are covered by the default classpath of a webapp, e.g. webapp's /WEB-INF/lib and /WEB-INF/classes, server's /lib, or JDK/JRE's /lib. If the propertiesfile is webapp-specific, best is to place it in /WEB-INF/classes. If you're developing a standard WAR project in an IDE, drop it in src folder (the project's source folder). If you're using a Maven project, drop it in /main/resources folder.

You can alternatively also put it somewhere outside the default classpath and add its path to the classpath of the appserver. In for example Tomcat you can configure it as shared.loader property of Tomcat/conf/catalina.properties.

If you have placed the foo.properties it in a Java package structure like com.example, then you need to load it as below

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...

Note that this path of a context class loader should not start with a /. Only when you're using a "relative" class loader such as SomeClass.class.getClassLoader(), then you indeed need to start it with a /.

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. Put it in webcontent

So that you can load it by ServletContext#getResourceAsStream() with a webcontent-relative path:

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

Note that I have demonstrated to place the file in /WEB-INF folder, otherwise it would have been public accessible by any webbrowser. Also note that the ServletContext is in any HttpServlet class just accessible by the inherited GenericServlet#getServletContext() and in Filter by FilterConfig#getServletContext(). In case you're not in a servlet class, it's usually just injectable via @Inject.


3. Put it in local disk file system

So that you can load it the usual java.io way with an absolute local disk file system path:

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

Note the importance of using an absolute path. Relative local disk file system paths are an absolute no-go in a Java EE web application. See also the first "See also" link below.


Which to choose?

Just weigh the advantages/disadvantages in your own opinion of maintainability.

If the properties files are "static" and never needs to change during runtime, then you could keep them in the WAR.

If you prefer being able to edit properties files from outside the web application without the need to rebuild and redeploy the WAR every time, then put it in the classpath outside the project (if necessary add the directory to the classpath).

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.

See also:

舟遥客 2024-08-26 18:08:32

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

我经历了惨痛的教训,如果您在 Eclipse 中“复制”一个 Web 项目,它会从任何源文件夹进行清理/重建。就我而言,我从 POJO java 库添加了一个“链接源目录”,它将编译到 WEB-INF/classes 文件夹。在该项目(而不是 Web 应用程序项目)中进行清理/重建会导致同样的问题。

我考虑过将我的confs放在POJO src文件夹中,但是这些confs都是针对WEB-INF/lib文件夹中的第3方库(例如Quartz或URLRewrite)的,因此没有有道理。我计划测试将其放入网络项目的“src”文件夹中,但该文件夹当前为空,并且其中包含conf文件似乎不太优雅。

因此,我投票支持将conf文件放在classes文件夹旁边的WEB-INF/commonConfFolder/filename.properties中,这是Balus选项2。

Word of warning: if you put config files in your WEB-INF/classes folder, and your IDE, say Eclipse, does a clean/rebuild, it will nuke your conf files unless they were in the Java source directory. BalusC's great answer alludes to that in option 1 but I wanted to add emphasis.

I learned the hard way that if you "copy" a web project in Eclipse, it does a clean/rebuild from any source folders. In my case I had added a "linked source dir" from our POJO java library, it would compile to the WEB-INF/classes folder. Doing a clean/rebuild in that project (not the web app project) caused the same problem.

I thought about putting my confs in the POJO src folder, but these confs are all for 3rd party libs (like Quartz or URLRewrite) that are in the WEB-INF/lib folder, so that didn't make sense. I plan to test putting it in the web projects "src" folder when i get around to it, but that folder is currently empty and having conf files in it seems inelegant.

So I vote for putting conf files in WEB-INF/commonConfFolder/filename.properties, next to the classes folder, which is Balus option 2.

送你一个梦 2024-08-26 18:08:32

例如:在 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.

Ex: In web.xml file the tag

<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>

And chat.properties you can declare your properties like this

For Ex :

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.
枕梦 2024-08-26 18:08:32

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

It just needs to be in the classpath (aka make sure it ends up under /WEB-INF/classes in the .war as part of the build).

路弥 2024-08-26 18:08:32

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

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

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

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

You can you with your source folder so whenever you build, those files are automatically copied to the classes directory.

Instead of using properties file, use XML file.

If the data is too small, you can even use web.xml for accessing the properties.

Please note that any of these approach will require app server restart for changes to be reflected.

你的背包 2024-08-26 18:08:32

假设您的代码正在寻找文件 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

Assume your code is looking for the file say app.properties. Copy this file to any dir and add this dir to classpath, by creating a setenv.sh in the bin dir of tomcat.

In your setenv.sh of tomcat( if this file is not existing, create one , tomcat will load this setenv.sh file.

#!/bin/sh
CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

You should not have your properties files in ./webapps//WEB-INF/classes/app.properties

Tomcat class loader will override the with the one from WEB-INF/classes/

A good read:
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文