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

san*_*dge 215 configuration resources servlets java-ee properties-file

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

Bal*_*usC 455

这是你的选择.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);
Run Code Online (Sandbox Code Playgroud)

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属性Tomcat/conf/catalina.properties.

如果您已将foo.properties它放在Java包结构中com.example,那么您需要按如下所示加载它

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Run Code Online (Sandbox Code Playgroud)

请注意,上下文类加载器的此路径不应以a开头/.只有当你使用"亲戚"类加载器时SomeClass.class.getClassLoader(),你确实需要用一个启动它/.

ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
Run Code Online (Sandbox Code Playgroud)

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


2.把它放在webcontent中

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

InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Run Code Online (Sandbox Code Playgroud)

请注意,我已经演示将文件放在/WEB-INF文件夹中,否则任何webbrowser都可以公开访问它.另请注意,ServletContext所有HttpServlet类都可以通过继承GenericServlet#getServletContext()和in Filter来访问FilterConfig#getServletContext().如果您不在servlet类中,它通常只是可注入的@Inject.


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

因此,您可以java.io使用绝对本地磁盘文件系统路径以常规方式加载它:

InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Run Code Online (Sandbox Code Playgroud)

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


选择哪个?

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

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

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

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

也可以看看:

  • @Blankman他可能意味着创建一个新文件夹,将所有自定义配置文件放在那里,并将该文件夹添加到类路径中.所以:1)在某处创建一个名为'appconfs'的文件夹(甚至可能是`/ etc/appconfs` 2)将该文件夹添加到app server/domain的类路径中.第二步是app server特定的,我认为没有通用的例子. (4认同)
  • "我个人更喜欢将它放在项目之外的类路径中(添加类路径的新路径)"混淆,你能举个例子吗? (2认同)

小智 8

警告:如果您将配置文件放在您的WEB-INF/classes文件夹中,并且您的IDE(例如Eclipse)执行了清理/重建,它将会破坏您的conf文件,除非它们位于Java源目录中.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.


小智 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>
Run Code Online (Sandbox Code Playgroud)

而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.
Run Code Online (Sandbox Code Playgroud)


Tay*_*ese 5

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