イントロと基本的な実装
まず最初に、少なくともURLStreamHandlerが必要になります。これにより、特定のURLへの接続が実際に開かれます。これは単に呼び出されることに注意してくださいHandler
。これにより、指定が可能になりjava -Djava.protocol.handler.pkgs=org.my.protocols
、サポートされるプロトコルとして「単純な」パッケージ名(この場合は「クラスパス」)を使用して自動的に選択されます。
使用法
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();
}
}
起動に関する問題
理由です-あなたの私に似ているものならば、あなたは(私の場合、私はJavaのWebStartのように開き、私のオプションを維持したいどこかであなたを得るために打ち上げでプロパティ設定中に依存したくない
、私はこのすべてを必要とします)。
回避策/拡張機能
手動コードハンドラー仕様
コードを制御すれば、
new URL(null, "classpath:some/package/resource.extension", new org.my.protocols.classpath.Handler(ClassLoader.getSystemClassLoader()))
これは、ハンドラーを使用して接続を開きます。
しかし、繰り返しますが、これを行うにはURLが必要ないため、これは満足のいくものではありません。これは、制御できない(または制御したくない)libがURLを要求するためです。
JVMハンドラーの登録
最終的なオプションはURLStreamHandlerFactory
、jvm全体ですべてのURLを処理するを登録することです。
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()
は、構成済みのファクトリーを呼び出します。次にnew URL("classpath:org/my/package/resource.extension")
、最初の例のように実行してください。
JVMハンドラー登録の問題
このメソッドはJVMごとに1回だけ呼び出すことができ、Tomcatはこのメソッドを使用してJNDIハンドラー(AFAIK)を登録することに注意してください。Jettyを試してください(私がします)。最悪の場合、最初にメソッドを使用してから、回避する必要があります。
ライセンス
私はこれをパブリックドメインにリリースします。変更したい場合は、どこかでOSSプロジェクトを開始し、詳細をここにコメントしてください。より適切な実装は、URLStreamHandlerFactory
を使用してごとにThreadLocal
を格納することです。私もあなたに私の変更とテストクラスを与えます。URLStreamHandler
Thread.currentThread().getContextClassLoader()
com.github.fommil.common-utils
Sonatypeを介してすぐに更新およびリリースする予定のパッケージの一部として含めることができます。