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

时间:2011-10-31 09:52:17

标签: jsf internationalization resources properties-file

我正在尝试访问我在代码中的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,"insetation.stat_codes.properties“等,变量foo都是null。类似的问题是{{3}但是,那里也没有有用的答案。

2 个答案:

答案 0 :(得分:23)

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

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

另见:

答案 1 :(得分:1)

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

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