Giriş ve temel uygulama
Öncelikle, en azından bir URLStreamHandler'a ihtiyacınız olacak. Bu aslında belirli bir URL'ye bağlantıyı açar. Bunun basit bir şekilde adlandırıldığına dikkat edin Handler
; bu, belirtmenize izin verir java -Djava.protocol.handler.pkgs=org.my.protocols
ve desteklenen protokol olarak "basit" paket adı kullanılarak (bu durumda "sınıf yolu") otomatik olarak alınacaktır.
kullanım
new URL("classpath:org/my/package/resource.extension").openConnection();
kod
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();
}
}
Başlatma sorunları
Neden -, bir yere almak için piyasaya bir özellik olmaktan sette güvenmek istemiyorum benim gibiyseniz şey sen ise (benim durumumda, benim seçenekleri Java WebStart gibi açık tutmak ister
ben bütün bu ihtiyaç ).
Geçici Çözümler / Geliştirmeleri
Manuel kod İşleyici özellikleri
Kodu kontrol ederseniz,
new URL(null, "classpath:some/package/resource.extension", new org.my.protocols.classpath.Handler(ClassLoader.getSystemClassLoader()))
ve bu bağlantıyı açmak için işleyicinizi kullanır.
Ama yine de, bunu yapmak için bir URL'ye ihtiyacınız olmadığından, bu tatmin edici olmaktan daha az - bunu yapmak istiyorsunuz çünkü kontrol edemediğiniz (veya istemediğiniz) bazı lib'ler URL istiyor ...
JVM İşleyici kaydı
Nihai seçenek, URLStreamHandlerFactory
jvm'deki tüm URL'leri işleyecek bir kayıt yapmaktır:
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);
}
}
İşleyiciyi kaydetmek URL.setURLStreamHandlerFactory()
için yapılandırılmış fabrika ile arayın . O zaman new URL("classpath:org/my/package/resource.extension")
ilk örneği beğen ve git.
JVM İşleyici Kayıt Sorunu
Bu yöntemin JVM başına yalnızca bir kez çağrılabileceğini ve Tomcat'in bir JNDI işleyicisini (AFAIK) kaydetmek için bu yöntemi kullanacağını unutmayın. İskele deneyin (ben olacağım); en kötüsü, önce yöntemi kullanabilirsiniz ve daha sonra etrafınızda çalışmak zorunda!
Lisans
Bunu kamu malı olarak yayınlıyorum ve değiştirmek istediğinizde bir yerde bir OSS projesi başlatmanızı ve burada ayrıntılarla yorum yapmanızı rica ediyorum. Daha iyi bir uygulama bir var olacaktır URLStreamHandlerFactory
that use ThreadLocal
mağaza için s URLStreamHandler
ler her biri için Thread.currentThread().getContextClassLoader()
. Size modifikasyonlarımı ve test sınıflarımı bile vereceğim.
com.github.fommil.common-utils
Sonatype aracılığıyla yakında güncellemeyi ve yayınlamayı planladığım paketimin bir parçası olarak ekleyebilirim.