소개 및 기본 구현
먼저 최소한 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();
}
}
발사 문제
왜 - 당신이 어딘가에 당신을 얻기 위해 발사의 속성 인 세트에 의존하지 않으려는 저 같이 아무것도 당신이 경우 (제 경우에, 나는 내 옵션은 자바 웹 시작처럼 열 유지하려면
내가 이 모든 필요 ).
해결 방법 / 향상
수동 코드 처리기 사양
코드를 제어하면 할 수 있습니다
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은이 메소드를 사용하여 AFAIK (JNDI 핸들러)를 등록합니다. 부두를 시도하십시오 (나는 될 것이다); 최악의 경우, 먼저이 방법을 사용할 수 있으며 해결해야합니다!
특허
나는 이것을 공개 도메인에 공개하고 수정을 원한다면 어딘가에 OSS 프로젝트를 시작하고 여기에 세부 사항을 언급하십시오. 더 나은 구현은 URLStreamHandlerFactory
을 사용 하여 각각 ThreadLocal
을 저장 URLStreamHandler
하는 것 Thread.currentThread().getContextClassLoader()
입니다. 나는 당신에게 나의 수정과 시험 수업을 줄 것이다.
com.github.fommil.common-utils
패키지의 일부로 Sonatype을 통해 곧 업데이트 및 릴리스 할 계획을 포함시킬 수 있습니다.