URL для загрузки ресурсов из пути к классам в Java - PullRequest
189 голосов
/ 14 мая 2009

В Java вы можете загружать все виды ресурсов, используя один и тот же API, но с разными протоколами URL:

file:///tmp.txt
http://127.0.0.1:8080/a.properties
jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class

Это прекрасно отделяет фактическую загрузку ресурса от приложения, которому нужен ресурс, и поскольку URL-адрес является просто строкой, загрузка ресурса также очень легко настраивается.

Есть ли протокол для загрузки ресурсов с использованием текущего загрузчика классов? Это похоже на протокол Jar, за исключением того, что мне не нужно знать, из какого файла JAR или папки классов поступает ресурс.

Конечно, я могу сделать это, используя Class.getResourceAsStream("a.xml"), но это потребует от меня использования другого API и, следовательно, изменений в существующем коде. Я хочу использовать это во всех местах, где я уже могу указать URL-адрес ресурса, просто обновив файл свойств.

Ответы [ 14 ]

2 голосов
/ 14 мая 2009

Я не знаю, есть ли уже, но вы можете сделать это сами легко.

Этот пример другого протокола выглядит для меня как шаблон фасада. У вас есть общий интерфейс, когда для каждого случая существуют разные реализации.

Вы можете использовать тот же принцип, создать класс ResourceLoader, который берет строку из файла свойств и проверяет наш собственный протокол

myprotocol:a.xml
myprotocol:file:///tmp.txt
myprotocol:http://127.0.0.1:8080/a.properties
myprotocol:jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class

удаляет протокол myprotocol: с начала строки, а затем принимает решение о том, каким способом загрузить ресурс, и просто предоставляет вам ресурс.

1 голос
/ 23 ноября 2018

Если у вас есть tomcat на пути к классам, это просто:

TomcatURLStreamHandlerFactory.register();

Это зарегистрирует обработчики для протоколов "war" и "classpath".

0 голосов
/ 01 февраля 2018

В приложении Spring Boot я использовал следующее, чтобы получить URL файла,

Thread.currentThread().getContextClassLoader().getResource("PromotionalOfferIdServiceV2.wsdl")
0 голосов
/ 29 сентября 2015

Я стараюсь избегать класса URL и вместо этого полагаюсь на URI. Таким образом, для вещей, которые требуют URL, где я хотел бы сделать Spring Resource, как поиск без Spring, я делаю следующее:

public static URL toURL(URI u, ClassLoader loader) throws MalformedURLException {
    if ("classpath".equals(u.getScheme())) {
        String path = u.getPath();
        if (path.startsWith("/")){
            path = path.substring("/".length());
        }
        return loader.getResource(path);
    }
    else if (u.getScheme() == null && u.getPath() != null) {
        //Assume that its a file.
        return new File(u.getPath()).toURI().toURL();
    }
    else {
        return u.toURL();
    }
}

Для создания URI вы можете использовать URI.create(..). Этот способ также лучше, потому что вы управляете ClassLoader, который будет выполнять поиск ресурса.

Я заметил некоторые другие ответы, пытавшиеся проанализировать URL-адрес как строку для определения схемы. Я думаю, что лучше обойти URI и использовать его для анализа.

Я на самом деле недавно подал заявку на решение проблемы, когда Spring Source попросил их отделить свой код ресурса от core, чтобы вам не понадобились все остальные компоненты Spring. 1017 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...