Вы можете попытаться передать значение региона в качестве параметра для вашего строкового ресурса
<string name="my_endpoint">https://%1$s-endpoint.mysite.com</string>
, а затем получить значение конечной точки следующим образом
String endpoint = getString(R.string.my_endpoint, customer.region)
у вас есть только одна строка в вашем файле strings.xml , но здесь есть слабое место, если конечная точка для каждого региона не имеет этого ключа.
Во-первых, вам понадобится как минимум URLStreamHandler. Это фактически откроет соединение с заданным URL-адресом. Обратите внимание, что это просто называется Handler
; это позволяет указать java -Djava.protocol.handler.pkgs = org.my.protocols
, и он будет автоматически выбран с использованием "простого" имени пакета в качестве поддерживаемого протокола (в данном случае " classpath ").
new URL("classpath:org/my/package/resource.extension").openConnection();
package org.my.protocols.classpath;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
/** A {@link URLStreamHandler} that handles resources on the classpath. */
public class Handler extends URLStreamHandler {
/** The classloader to find resources from. */
private final ClassLoader classLoader;
public Handler() {
this.classLoader = getClass().getClassLoader();
}
public Handler(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
protected URLConnection openConnection(URL u) throws IOException {
final URL resourceUrl = classLoader.getResource(u.getPath());
return resourceUrl.openConnection();
}
}
Если вы управляете кодом, вы можете выполнить
new URL(null, "classpath:some/package/resource.extension", new org.my.protocols.classpath.Handler(ClassLoader.getSystemClassLoader()))
, и это будет использовать ваш обработчик для открытия соединения.
Но опять же, это менее чем удовлетворительно , поскольку для этого вам не нужен URL - вы хотите это сделать, потому что некоторая библиотека, которую вы не можете (или не хотите) контролировать, хочет URL ...
Окончательный вариант - зарегистрировать URLStreamHandlerFactory
, который будет обрабатывать все URL-адреса в jvm:
package my.org.url;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.HashMap;
import java.util.Map;
class ConfigurableStreamHandlerFactory implements URLStreamHandlerFactory {
private final Map<String, URLStreamHandler> protocolHandlers;
public ConfigurableStreamHandlerFactory(String protocol, URLStreamHandler urlHandler) {
protocolHandlers = new HashMap<String, URLStreamHandler>();
addHandler(protocol, urlHandler);
}
public void addHandler(String protocol, URLStreamHandler urlHandler) {
protocolHandlers.put(protocol, urlHandler);
}
public URLStreamHandler createURLStreamHandler(String protocol) {
return protocolHandlers.get(protocol);
}
}
Чтобы зарегистрировать обработчик, вызовите URL.setURLStreamHandlerFactory ()
с настроенной фабрикой. Затем введите новый URL ("путь к классам: org / my / package / resource.extension")
, как в первом примере, и вперед.
Обратите внимание, что этот метод может быть вызван только один раз для каждой JVM, и обратите внимание, что Tomcat будет использовать этот метод для регистрации обработчика JNDI (AFAIK). Попробуйте Jetty (буду); в худшем случае вы можете сначала использовать этот метод, а затем он должен обойти вас!
Я передаю это в общественное достояние и прошу, если вы хотите изменить, запустите где-нибудь проект OSS и прокомментируйте здесь с подробностями. Лучшей реализацией было бы иметь URLStreamHandlerFactory
, который использует ThreadLocal
для хранения URLStreamHandler
s для каждого Thread.currentThread (). GetContextClassLoader () [)
. Я даже дам вам свои модификации и тестовые классы.
Расширение к Ответ Дилумса :
Без изменения кода вам, вероятно, потребуется реализовать собственные реализации интерфейсов, связанных с URL, как рекомендует Дилум. Чтобы упростить вам задачу, я могу порекомендовать посмотреть исходники Ресурсы Spring Framework . Хотя код не имеет формы обработчика потока, он был разработан для того, чтобы делать именно то, что вы хотите делать, и находится под лицензией ASL 2.0, что делает его достаточно дружественным для повторного использования в вашем коде с должным уважением.
Я не знаю, есть ли он уже, но вы можете легко сделать это сами.
Этот пример различных протоколов выглядит для меня как образец фасада. У вас есть общий интерфейс, когда есть разные реализации для каждого случая.
Вы можете использовать тот же принцип, создать класс 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: с начала строки, а затем принимает решение, каким способом загрузить ресурс, и просто предоставляет вам ресурс.
(Аналогично ответу Аздера , но немного другой такт.)
Я не верю, что существует предопределенный обработчик протокола для содержимого из пути к классам. (Так называемый classpath:
протокол.)
Однако Java позволяет добавлять собственные протоколы. Это достигается путем предоставления конкретных реализаций java.net.URLStreamHandler
и java.net.URLConnection
.
В этой статье описывается, как можно реализовать настраиваемый обработчик потока: http://java.sun.com/developer/onlineTraining/protocolhandlers/ .