介绍和基本实现
首先,您至少需要一个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来做到这一点 - 你想这样做,因为一些你不能(或不想)控制的库想要网址......
JVM 处理程序注册
最终的选择是注册一个将处理jvm上所有URL的:URLStreamHandlerFactory
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
,它使用ThreadLocal
s来存储每个Thread.currentThread().getContextClassLoader()
的URLStreamHandler
s。我甚至会给你我的修改和测试类。