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

评论

JNDI也许是一个解决方案?

#1 楼

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

1。将其放在classpath
中,以便您可以通过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。如果properties文件是特定于Web应用程序的,则最好将其放在/WEB-INF/classes中。如果要在IDE中开发标准WAR项目,请将其放在src文件夹(项目的源文件夹)中。如果您正在使用Maven项目,请将其放在/main/resources文件夹中。
您也可以将其放在默认类路径之外的某个位置,并将其路径添加到appserver的类路径中。例如,在Tomcat中,您可以将其配置为shared.loaderTomcat/conf/catalina.properties属性。
如果将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文件夹中,否则任何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文件中。
另请参见:

getResourceAsStream()vs FileInputStream
将目录添加到tomcat类路径
以编程方式访问JSF应用程序中的属性文件


评论


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

–布兰克曼
2011-12-18 18:32

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

– Tuukka Mustonen
2012年1月3日15:15



Re:2:为什么“ WEB-INF / filename.properties”和“ /WEB-INF/filename.properties”(请注意/开头)都可以工作?有什么理由比另一个更喜欢吗?

– Mr_and_Mrs_D
2013年9月7日14:57



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

–阿伦·拉贾(Arun Raja)
15年4月24日在7:25

@Techguy:当路径无效或实际上没有将资源放置在应该放置的位置时,它将返回null。

– BalusC
8月21日14:08



#2 楼

警告:如果将配置文件放在WEB-INF/classes文件夹中,并且您的IDE(例如Eclipse)执行清理/重建,除非您将conf文件放在Java源目录中,否则它将破坏conf文件。 BalusC的一个很好的答案在选项1中提到了这一点,但是我想强调一点。文件夹。在我的情况下,我从POJO Java库中添加了一个“链接的源目录”,它将编译到WEB-INF/classes文件夹中。在该项目(不是Web应用程序项目)中执行清理/重建会导致相同的问题。

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

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

评论


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

–JesseBoyd
17年9月8日21:00

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

–JesseBoyd
17年9月8日在21:03



#3 楼

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


#4 楼

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

评论


您好,谢谢,但它告诉我找不到指定的文件,是的,路径问题如何给出路径

– sansknwoledge
10年1月29日在10:32

#5 楼

您可以使用源文件夹,以便在构建时将这些文件自动复制到classes目录。

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

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

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

评论


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

– sansknwoledge
10年1月29日在10:34

如果您的文件最终位于WEB-INF / classes文件夹中,则会自动设置为classpath

–卡帕克
2010-1-30在8:28

#6 楼

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