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

时间:2010-01-29 09:44:05

标签: servlets java-ee configuration resources properties-file

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

6 个答案:

答案 0 :(得分:444)

这是你的选择。 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的/WEB-INF/lib/WEB-INF/classes,服务器的/lib或JDK / JRE的/lib。如果propertiesfile是特定于webapp的,最好将其放在/WEB-INF/classes中。如果您正在IDE中开发标准WAR项目,请将其放在src文件夹(项目的源文件夹)中。如果您正在使用Maven项目,请将其放在/main/resources文件夹中。

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

如果您已将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()启动它。

/

但是,属性文件的可见性取决于所讨论的类加载器。只有加载类的类加载器才能看到它。所以,如果该类是由例如服务器通用类加载器而不是webapp类加载器,属性文件在webapp本身内部,然后它是不可见的。上下文类加载器是您最安全的选择,因此您可以将属性文件“无处不在”放在类路径中和/或您打算能够从webapp上覆盖服务器提供的文件。


2。把它放在webcontent

这样您就可以通过ServletContext#getResourceAsStream()使用webcontent-relative路径加载它:

ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...

请注意,我已经演示将文件放在InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties"); // ... 文件夹中,否则任何webbrowser都可以公开访问该文件。另请注意,/WEB-INF类可以在任何ServletContext类中使用,只能由继承的GenericServlet#getServletContext()访问,HttpServlet只能由FilterConfig#getServletContext()访问。如果你不在servlet类中,它通常只能通过Filter注入。


3。将其放在本地磁盘文件系统

这样您就可以使用绝对本地磁盘文件系统路径以通常的@Inject方式加载它:

java.io

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


选择哪个?

只需权衡自己对可维护性的看法的优缺点。

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

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

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

另见:

答案 1 :(得分:8)

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

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

我考虑过将我的confs放在POJO src文件夹中,但这些confs都适用于WEB-INF/lib文件夹中的第三方库(如Quartz或URLRewrite),因此没有意义。我计划测试将它放在web项目“src”文件夹中,当我开始使用它时,但该文件夹当前是空的,并且其中包含conf文件似乎不够优雅。

所以我投票赞成将WEB-INF/commonConfFolder/filename.properties next 中的conf文件放到classes文件夹中,这是Balus选项2。

答案 2 :(得分:6)

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>

并且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.

答案 3 :(得分:5)

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

答案 4 :(得分:3)

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

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

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

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

答案 5 :(得分:1)

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