Программный доступ к файлу свойств в приложении JSF - PullRequest
11 голосов
/ 31 октября 2011

Я пытаюсь получить доступ к файлу свойств i18n, который я использую в своем приложении JSF в коде. (Идея состоит в том, чтобы иметь страницу, отображающую ее ключи и значения в виде таблицы.)

Проект является проектом maven и находится в папке src / resources / localization и развернут в файле war в WEB-INF \ classes \ localization \

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

Но переменная foo оказывается нулевой, независимо от того, какую переменную пути я установил, /WEB-INF/classes/localization/stat_codes.properties, "localization.stat_codes.properties" и т. Д. Аналогичный вопрос здесь , но там также нет полезного ответа.

Ответы [ 2 ]

23 голосов
/ 31 октября 2011

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, не обязательно знает о файлах, которые есть в /WEB-INF/classes веб-приложения. Так что префикс пути с / не обязательно будет решением, он все равно вернет null.

Если вы можете гарантировать, что текущий класс виден тем же загрузчиком классов, что и файлы свойств (поскольку они находятся в том же самом корне пути к классам, например, /WEB-INF/classes, то вам действительно следует использовать

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

Но если в какой-то момент файлы свойств будут экспортированы из-за более простого обслуживания / редактирования во время выполнения, так что вам не нужно перестраивать / повторно развертывать / перезапускать веб-приложение всякий раз, когда вы хотите отредактировать файлы, тогда приведенный выше строка кода, скорее всего, тоже потерпит неудачу. Внешнее местоположение будет доступно только другому загрузчику классов. Каноническое решение состоит в том, чтобы использовать загрузчик классов контекста потока в качестве отправной точки, вместо этого он имеет доступ к всем ресурсам в пути к классам.

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

(обратите внимание, что этот путь не может начинаться с /, он всегда относительно общего корня)

Смотри также:

1 голос
/ 31 октября 2011

Кажется, что виновником является объект prop, я предполагал, что любой объект будет работать, но это должен быть текущий объект (this), для которого, похоже, вызывается метод getClass(). Кроме того, путь должен начинаться с /, поскольку каталог localization находится в WEB-INF/classes.

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