Java 如何在 Web 应用程序中读取属性文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3160691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:57:44  来源:igfitidea点击:

How to read properties file in web application?

javaproperties

提问by Roman

Properties file location is WEB-INF/classes/auth.properties.

属性文件位置是WEB-INF/classes/auth.properties.

I cannot use JSF-specific ways (with ExternalContext) because I need properties file in a service module which doesn't have a dependency on a web-module.

我不能使用 JSF 特定的方式(使用 ExternalContext),因为我需要在不依赖于 web 模块的服务模块中的属性文件。

I've already tried

我已经试过了

MyService.class.getClassLoader().getResourceAsStream("/WEB-INF/classes/auth.properties");

but it returns null.

但它返回null

I've also tried to read it with FileInputStreambut it requires the full path what is unacceptable.

我也试过用FileInputStream它来阅读它,但它需要完整的路径,这是不可接受的。

Any ideas?

有任何想法吗?

采纳答案by BalusC

Several notes:

几个注意事项:

  1. You should prefer the ClassLoaderas returned by Thread#getContextClassLoader().

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    

    This returns the parentmost classloader which has access to allresources. The Class#getClassLoader()will only return the (child) classloader of the class in question which may not per se have access to the desired resource. It will always work in environments with a single classloader, but not always in environments with a complex hierarchy of classloaders like webapps.

  2. The /WEB-INFfolder is not in the root of the classpath. The /WEB-INF/classesfolder is. So you need to load the properties files relative to that.

    classLoader.getResourceAsStream("/auth.properties");
    

    If you opt for using the Thread#getContextClassLoader(), remove the leading /.

  1. 你应该更喜欢ClassLoader通过返回的Thread#getContextClassLoader()

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    

    这将返回可以访问所有资源的最父类加载器。该Class#getClassLoader()会只返回类的(子)类加载器中可能本身并不访问所需的资源问题。它始终适用于具有单个类加载器的环境,但并不总是适用于具有复杂类加载器层次结构(如 webapps)的环境。

  2. /WEB-INF文件夹不在类路径的根目录中。该/WEB-INF/classes文件夹。因此,您需要加载与此相关的属性文件。

    classLoader.getResourceAsStream("/auth.properties");
    

    如果您选择使用Thread#getContextClassLoader(),请删除前导/.

The JSF-specific ExternalContext#getResourceAsStream()which uses ServletContext#getResourceAsStream()"under the hoods" only returns resources from the webcontent (there where the /WEB-INFfolder is sitting), not from the classpath.

特定于 JSF 的ExternalContext#getResourceAsStream()使用ServletContext#getResourceAsStream()“幕后”仅从 web 内容(/WEB-INF文件夹所在的位置)返回资源,而不是从类路径。

回答by Jesper

Try this:

尝试这个:

MyService.class.getClassLoader().getResourceAsStream("/auth.properties");

Reading files with getResourceAsStreamlooks on the classpath to find the resource to load. Since the classesdirectory is in the classpath for your webapp, referring to the file as /auth.propertiesshould work.

getResourceAsStream在类路径上读取文件以查找要加载的资源。由于该classes目录位于您的 web 应用程序的类路径中,因此引用该文件/auth.properties应该可以工作。

回答by Gelvis

ResourceBundle (http://download.oracle.com/javase/6/docs/api/java/util/ResourceBundle.html) resolve most of the problems with a relative/absotule path for Properties Files.

ResourceBundle ( http://download.oracle.com/javase/6/docs/api/java/util/ResourceBundle.html) 通过属性文件的相对/绝对路径解决了大多数问题。

It uses the the Resource class and point it to a Dummy Class to make reference to a properties file.

它使用 Resource 类并将其指向一个虚拟类以引用属性文件。

For example:

例如:

  1. You a have file called MAINProperties.properties and inside it there is a property: mail.host=foo.example.com
  2. Create a Dummy Class called MAINProperties without nothing.
  3. Use the following code:

    ResourceBundle.getBundle("com.example.com.MAINProperties").getProperty("mail.host")

  1. 你有一个名为 MAINProperties.properties 的文件,里面有一个属性:mail.host=foo.example.com
  2. 创建一个名为 MAINProperties 的虚拟类,没有任何内容。
  3. 使用以下代码:

    ResourceBundle.getBundle("com.example.com.MAINProperties").getProperty("mail.host")

And That's it. No InputStreams Required.

就是这样。不需要输入流。

P.D. Apache Commons has a Library Called Apache Commons Configuration that has a lot of capabilities (reloadable files, multiple domain types) that could be used in combination of the above.

PD Apache Commons 有一个名为 Apache Commons Configuration 的库,它具有许多功能(可重新加载的文件、多个域类型),可以结合上述功能使用。