以编程方式访问 JSF 应用程序中的属性文件

Posted

技术标签:

【中文标题】以编程方式访问 JSF 应用程序中的属性文件【英文标题】:Accessing properties file in a JSF application programmatically 【发布时间】:2011-12-18 14:54:27 【问题描述】:

我正在尝试以代码访问我在 JSF 应用程序中使用的 i18n 属性文件。 (这个想法是有一个页面,实际上将其键和值显示为一个表。)

该项目是一个maven项目,在src/resources/localization文件夹下,并部署在WEB-INF\classes\localization\的war文件中

java.util.Properties prop = new java.util.Properties();
String path = "localization/stat_codes.properties";
InputStream foo = prop.getClass().getResourceAsStream(path);

但无论我将路径变量设置为 /WEB-INF/classes/localization/stat_codes.properties、“localization.stat_codes.properties”等,变量 foo 都为空。类似的问题是 here,但那里也没有有用的答案。

【问题讨论】:

【参考方案1】:

Class#getResourceAsStream() 可以采用相对于您在那里使用的Class 的位置作为起点的路径。因此,例如,如果该类位于 com.example 包中并且您请求路径 foo/filename.properties,那么它将实际上加载 com/example/foo/filename.properties 文件。但是如果你使用/foo/filename.properties,那么它实际上会从类路径根目录加载foo/filename.properties

所以,你的代码

java.util.Properties prop = new java.util.Properties();
String path = "localization/stat_codes.properties";
InputStream foo = prop.getClass().getResourceAsStream(path);

实际上寻找java/util/localization/stat_codes.properties文件。

但在具有复杂的多个类加载器层次结构的应用程序中,一个类加载器不是另一个。加载核心 Java 类的类加载器不一定知道 webapp 的/WEB-INF/classes 中的文件。所以用/前缀路径不一定是解决方案,它仍然会返回null

如果您可以保证当前类与属性文件在同一个类加载器中可见(因为它们位于类路径的同一子根目录中,例如/WEB-INF/classes,那么您确实应该使用

String path = "/localization/stat_codes.properties";
InputStream foo = this.getClass().getResourceAsStream(path);

但是,如果在某些时候,属性文件将被外部化,因为在运行时更容易维护/编辑,这样您就不需要在想要编辑文件时重新构建/重新部署/重新启动 webapp,那么上面代码行也可能会失败。外部化位置只能由不同的类加载器访问。规范的解决方案是使用线程的上下文类加载器作为起点,它可以访问类路径中的所有资源。

String path = "localization/stat_codes.properties";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream foo = loader.getResourceAsStream(path);

(注意这个不能走以/开头的路径,它总是相对于公共根)

另见:

Where to place and how to read configuration resource files in servlet based application? ExternalContext#getResourceAsStream() returns null, where to place the resource file?

【讨论】:

【参考方案2】:

罪魁祸首似乎是prop 对象,我认为任何对象都可以工作,但它似乎必须是调用方法getClass() 的当前对象(this)。此外,路径应以/ 开头,因为localization 目录位于WEB-INF/classes 中。

String path = "localization/stat_codes.properties";
InputStream foo = this.getClass().getResourceAsStream(path);

【讨论】:

以上是关于以编程方式访问 JSF 应用程序中的属性文件的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式注册 JSF 托管 bean?

jsf从属性文件中的数组访问元素

JSF 2.0 在整个会话中从浏览器和以编程方式设置区域设置 [重复]

以编程方式访问 iOS 上的应用程序图标

有没有办法以编程方式检测用户何时按下浏览器中的F5按钮?

Watchkit:以编程方式设置全局色调