介绍和基本实现
首先,您至少需要一个 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 来执行此操作 - 您想要这样做是因为您无法(或不想)控制的某些库想要 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 只能调用此方法一次,请注意 Tomcat 将使用此方法注册 JNDI 处理程序 (AFAIK)。试试码头(我会的);在最坏的情况下,您可以先使用该方法,然后它必须在您周围工作!
执照
我将其发布到公共领域,并询问您是否希望修改您在某处启动 OSS 项目并在此处评论详细信息。更好的实现是URLStreamHandlerFactory
使用s为每个ThreadLocal
s 存储s 。我什至会给你我的修改和测试课程。URLStreamHandler
Thread.currentThread().getContextClassLoader()