Загрузка ресурсов и конфигурации в проекте maven

Я использую Maven для настольного приложения. Я читал о макет каталога Maven standart и у меня есть эта структура проекта на данный момент:

App
|-- pom.xml
`-- src
    |-- main
        |-- java
        |   `-- java classes
        |-- resources
        |   `-- images
        |       `-- app images
        `--config
           `--config.xml

Я хочу найти способ загрузить мои ресурсы и файлы конфигурации. Я прочитал несколько статей и тем и нашел это (упрощенный пример из моего кода):

//class for loading config
public class Preferences {
    public Preferences() {
        InputStream image = Preferences.class.getResourceAsStream("images/image.png");
        InputStream config = Preferences.class.getResourceAsStream("config.xml");
    }        
}

но переменные image и config содержат null. Я пробовал разные варианты загрузки (из корневой папки, с этим.getClass() вместо Предпочтения.class и другие), но у меня всегда есть null. Я действительно не понимаю эту систему загрузки ресурсов и я не нашел хорошую документацию о нем. Было бы здорово, если кто-нибудь даст хорошее объяснение этому механизму (или просто даст ссылку на документы). Итак, главный вопрос: Как я могу загрузить свои ресурсы и файлы конфигурации?

5 ответов


Я думаю, что нашел решение. Как пишут Juned Ahsan и mR_fr0g, мне нужно использовать класс ClassLoader вместо этого.getClass().методу getresource(). Но он работает только для папки ресурсов. Но maven позволяет добавлять другие папки в качестве папок ресурсов. Мне просто нужно было добавить этот раздел в pom.XML-код:

<build>
    <resources>
        <resource>
            <directory>src/main/config</directory>
        </resource>
    </resources>
</build>

и рабочий java-код:

InputStream image = this.getClass().getClassLoader().getResourceAsStream("images/image.png");
InputStream config = ClassLoader.getSystemResourceAsStream("config.xml");

можно использовать getResourceAsStream() метод java.lang.Class как вы сделали, но вы должны добавить / перед путем.


этот вопрос сложно.

1. Два метода с одинаковым именем

прежде всего, существуют два метода того же имени и той же подписи в этих двух классах:

java.lang.Class
java.lang.ClassLoader

у них одно и то же название:getResource(String)getResourceAsStream(String) - это так).

2. Они принимают параметры другой формат

затем, парам из них имеет другой формат:

  • метод java.lang.Class.getResouce<asStream>() можно путь С и без ведущего /, что приводит к различным стратегиям поиска ресурсов. Если путь не имеет /, Java будет искать ресурс в пакете / папке, где .class проживает файла. Если это так!--8-->, Java начнет поиск от корня пути к классам.
  • метод java.lang.ClassLoader.getResource<asStream>() принимает только путь без /, потому что он всегда ищет из classpath. В пути, основанном на classpath,/ не является допустимым символом. *

    *: как говорится в этом ответе:этого.getClass().getClassLoader().методу getresource("...") и NullPointerException

как добавить папку в classpath? В Eclipse мы решаем в контекстном меню проекта: "Путь сборки" - " настроить путь сборки..."и добавьте некоторую папку для сборки path.

3. Когда дело доходит до Maven

наконец, если проект является проектом Maven, по умолчанию src/main/resources находится в пути к классам, поэтому мы можем использовать

Class.getResource("/path-to-your-res");

или

ClassLoader.getResource("path-to-your-res");

, чтобы загрузить что-нибудь под src/main/resources.

если мы хотим добавить другую папку ресурсов, как вы упомянули, это делается в pom.xml. и они также добавляются в classpath, выполняемые Maven. Никакой дополнительной конфигурации не требуется.

4. Пример

например, если ваш config.ini под src/main/resources/settings, myAvatar.gif под src/main/images, вы можете сделать:

на pom.xml:

<build>
    <resources>
        <resource>
            <directory>src/main/images</directory>
        </resource>
    </resources>
</build>

в коде:

URL urlConfig = MyClass.class.getResource("/settings/config.ini"); //by default "src/main/resources/" is in classpath and no config needs to be changed.
InputStream inputAvatar = MyClass.class.getResourceAsStream("/myAvatar.gif"); //with changes in pom.xml now "src/main/images" is counted as resource folder, and added to classpath. So we use it directly.

мы должны использовать / выше.

или, с ClassLoader:

URL urlConfig = MyClass.class.getClassLoader().getResource("settings/config.ini"); //no leading "/"!!!
InputStream inputAvatar = MyClass.class.getClassLoader().getResourceAsStream("myAvatar.gif"); //no leading "/"!!!

public Preferences() {
    InputStream image = this.getClass().getClassLoader().getResourceAsStream("image.png");
    InputStream config = this.getClass().getClassLoader().getResourceAsStream("config.xml")
} 

Как насчет использования этого appraoch:

InputStream file = ClassLoader.getSystemResourceAsStream("res.txt");

или

InputStream file = Thread.currentThread().getContextClassLoader().getResourceAsStream("MyProperty.properties");

как у вас в настоящее время есть, это будет искать MyProperty.файл свойств в верхней части пути к классам. Это может быть в вашем каталоге src/main/resources или другой папке src-это будет зависеть от того, как построено ваше приложение (jar/war).

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


пытаюсь построить проект. Если вы просто поместите файлы в папку resources, вам нужно построить проект, чтобы скопировать новые файлы ресурсов в целевую папку