介绍和基本实现
首先,您将至少需要一个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();
}
}
启动问题
如果您像我一样,就不想依靠启动中设置的属性来将您带到某个地方(就我而言,我想像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只能调用一次此方法,请注意,Tomcat将使用此方法注册JNDI处理程序(AFAIK)。试试Jetty(我会的);最坏的情况是,您可以先使用该方法,然后它必须在您周围解决!
执照
我将其发布到公共领域,并询问是否要修改以在某个地方启动OSS项目并在此处提供详细信息。更好的实现是让每个URLStreamHandlerFactory
使用ThreadLocal
来存储。我什至会给您我的修改和测试课程。URLStreamHandler
Thread.currentThread().getContextClassLoader()
com.github.fommil.common-utils
计划通过Sonatype进行更新和发布的软件包作为软件包的一部分。