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


222

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


JNDI也许是一个解决方案?
罗勒·布尔克

Answers:


464

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


1.将其放在类路径中

这样就可以ClassLoader#getResourceAsStream()使用相对于classpath的路径加载它:

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

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

您也可以将其放置在默认类路径之外的某个位置,并将其路径添加到应用服务器的类路径。例如,在Tomcat中,您可以将其配置为的shared.loader属性Tomcat/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本身内部,则它是不可见的。上下文类加载器是您最安全的选择,因此您可以将属性文件“随处可见”放置在类路径中,并且/或者打算能够从Web应用程序覆盖服务器提供的文件。


2.放入网站内容

这样就可以ServletContext#getResourceAsStream()使用相对于webcontent的路径加载它:

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

请注意,我已经演示过将文件放置在文件/WEB-INF夹中,否则任何Web浏览器都可以公开访问该文件。还要注意的是,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()。重新部署后,deploy文件夹中的所有更改都将丢失,原因很简单,因为这些更改不会反映回原始WAR文件中。

也可以看看:


2
“我个人更喜欢将其放在项目外部的类路径中(将新路径添加到类路径中”)感到困惑,您能举个例子吗?
Blankman

4
@Blankman他可能意味着创建一个新文件夹,将所有自定义配置文件放在此处,然后将该文件夹添加到类路径中。因此:1)在某个位置创建一个名为“ appconfs”的文件夹(可能甚至是/etc/appconfs2),将该文件夹添加到应用服务器/域的类路径中。第二步是特定于应用程序服务器的,我认为没有通用的示例。
Tuukka Mustonen 2012年

Re:2:"WEB-INF/filename.properties"和和"/WEB-INF/filename.properties"(请注意/开头)为什么都起作用?有什么理由比另一个更喜欢吗?
Mr_and_Mrs_D 2013年

在过去的一天中,我已解决此问题。我无法加载我的属性文件。我可以从两个地方加载它。一个是系统目录,一个是本地驱动器。它与本地主机一起使用。但我想将其部署在亚马逊上。
阿伦·拉贾

我正在使用netbeans IDE,并将属性文件保留在Web页面/资源中。我尝试以“ ./Web Pages / resources / config.properties”访问它。我无法访问它。请帮我。
阿伦·拉贾

9

警告:如果将配置文件放在文件WEB-INF/classes夹中,并且您的IDE(例如Eclipse)进行清理/重建,则除非您的conf文件位于Java源目录中,否则它将破坏conf文件。BalusC的出色答案在选项1中提到了这一点,但我想强调一下。

我了解了很难的方法,即如果您在Eclipse中“复制” Web项目,它将从任何源文件夹中进行清理/重建。在我的情况下,我从POJO Java库中添加了一个“链接源目录”,它将编译到该WEB-INF/classes文件夹中。在该项目(不是Web应用程序项目)中执行清理/重建会导致相同的问题。

我曾考虑过将confs放在POJO src文件夹中,但是这些confs都是针对文件夹中的第三方库(例如Quartz或URLRewrite)的WEB-INF/lib,因此这没有任何意义。我打算测试将它放到Web项目的“ src”文件夹中,但是该文件夹当前为空,并且其中的conf文件似乎不太美观。

所以我投了把conf文件中WEB-INF/commonConfFolder/filename.properties未来的类文件夹,这是Balus选项2。


1
如果将配置文件放在WEB_INF的子文件夹中,那么如何到达它?我还没有运气说“configFiles / prop.properties”
JesseBoyd

好的,这确实可以将属性文件放在“ Java Resources / src /”下,但在我的一个软件包中就无法使用,并且需要位于src的根目录下。您对classes文件夹被破坏的警告是一个有效的问题。
JesseBoyd

6

例如:在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您可以像这样声明您的属性

对于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.

5

它只需要位于类路径中即可(也可以确保将其作为构建的一部分放在.war中的/ WEB-INF / classes下)。


嗨,感谢您的想法,但是它告诉我找不到指定的文件,是的,路径问题如何给出路径
sansknwoledge 2010年

3

您可以使用源文件夹,这样在每次构建时,这些文件都会自动复制到classes目录中。

代替使用属性文件,而使用XML文件。

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

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


我放在网页文件夹中,但无法访问它,但找不到文件错误即将来临,如何设置路径
sansknwoledge 2010年

1
如果文件最终位于WEB-INF / classes文件夹中,则会自动设置为类路径
Kalpak 2010年

2

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.