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

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

问题描述

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

解决方案

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






1。将它放在classpath中



这样就可以通过 ClassLoader#getResourceAsStream() 使用classpath-相对路径:

  ClassLoader classLoader = Thread.currentThread()。getContextClassLoader 
InputStream input = classLoader.getResourceAsStream(foo.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中,您可以将其配置为 Tomcat / conf / catalina.properties shared.loader 属性。 p>

如果您已将 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本身内,那么它是不可见的。上下文类加载器是你最安全的选择,所以你可以将属性文件无处不在放在类路径和/或你打算能够覆盖服务器提供的webapp上。






2。将它放在webcontent中



这样就可以通过 ServletContext#getResourceAsStream() 与web内容相对路径:

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

注意,我已经证明将文件放在 / WEB-INF 文件夹,否则任何webbrowser都可以访问。还要注意, ServletContext 在任何 HttpServlet 类中,只能通过继承的 GenericServlet#getServletContext() 过滤器中的 FilterConfig#getServletContext() 。如果你不是一个servlet类,它通常只能通过 @Inject 注入。






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



这样你可以加载通常的 java.io 本地磁盘文件系统路径:

  InputStream input = new FileInputStream(/ absolute / path / to / foo.properties); 
// ...

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






哪个选择?



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



如果属性文件是static,并且在运行时不需要更改,则可以将它们保留在WAR中。



如果你喜欢能够从web应用程序之外编辑属性文件,而不需要每次重新构建和重新部署WAR,那么将它放在项目外的类路径中(如果需要,可以将目录添加到类路径中) 。



如果您希望能够使用 Properties#store()方法以编程方式从Web应用程序中编辑属性文件,把它放在web应用程序之外。因为 Properties#store()需要一个 Writer ,所以不能使用磁盘文件系统路径。该路径可以作为VM参数或系统属性传递到Web应用程序。作为预防措施, 从不 strong>使用 getRealPath()



另请参阅:

$

b
$ b

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.

解决方案

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


1. Put it in classpath

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

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.

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.

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

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

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.


2. Put it in webcontent

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

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

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.


3. Put it in local disk file system

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

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.


Which to choose?

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

If the properties files are "static" and never needs to change during runtime, then you could keep them in the 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).

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.

See also:

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

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