在基于 servlet 的应用程序中放置以及如何读取配置资源文件? [英] Where to place and how to read configuration resource files in servlet based application?

查看:19
本文介绍了在基于 servlet 的应用程序中放置以及如何读取配置资源文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my web application I have to send email to set of predefined users like finance@xyz.com, 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.

推荐答案

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

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

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

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

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

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.

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

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.

如果你已经把foo.properties放在com.example这样的Java包结构中,那么你需要如下加载它

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");
// ...

请注意,上下文类加载器的此路径不应以 / 开头.仅当您使用亲戚"时类加载器,比如SomeClass.class.getClassLoader(),那么你确实需要以/开头.

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");
// ...

然而,属性文件的可见性取决于相关的类加载器.它只对与加载类相同的类加载器可见.所以,如果类是由例如加载的服务器公共类加载器而不是 webapp 类加载器,并且属性文件在 webapp 本身内部,那么它是不可见的.上下文类加载器是您最安全的选择,因此您可以将属性文件无处不在"放置在在类路径中和/或您打算能够从 web 应用程序覆盖服务器提供的一个.

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.

以便您可以通过 ServletContext#getResourceAsStream() 与 webcontent 相对路径:

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

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

请注意,我已演示将文件放在 /WEB-INF 文件夹中,否则任何网络浏览器都可以公开访问它.另请注意,ServletContext 位于任何 HttpServlet 类中,只能通过继承的 GenericServlet#getServletContext() 并在 Filter 中通过 FilterConfig#getServletContext().如果您不在 servlet 类中,它通常只能通过 @Inject 注入.

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.

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

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");
// ...

注意使用绝对路径的重要性.相对本地磁盘文件系统路径在 Java EE Web 应用程序中是绝对禁止的.另见第一个另见"链接如下.

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.

只需权衡自己对可维护性的看法.

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

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

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

如果您希望能够从 Web 应用程序外部编辑属性文件,而无需每次都重新构建和重新部署 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).

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

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.

这篇关于在基于 servlet 的应用程序中放置以及如何读取配置资源文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆