同学们在使用URL和HttpURLConnection这套类库时,对于这行代码:
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
执行后得到一个HttpURLConnection 对象会不会有这样的疑惑,HttpURLConnection 是一个抽象类,然而url.openConnection()却得到一个实例对象,这必定是某个类继承了HttpURLConnection类(其实输出一下们可以看到得到的是sun.net.www.protocol.http.HttpURLConnection对象),那么url.openConnection()是如何得到该类的对象实例的,其实URL底层是使用流协议处理程序和流协议处理程序工厂实现找到某协议对应的正确的HttpURLConnection的子类的。
通过下面几个步骤,可以自定义HttpURLConnection的子类,从而让url.openConnection()得到是你想要的对象!
步骤一:创建HttpURLConnection的子类:HttpURLConnectionImpl
public class HttpURLConnectionImpl extends HttpURLConnection{
protected HttpURLConnectionImpl(URL u) {
super(u);
}
@Override
public void disconnect() {
}
@Override
public boolean usingProxy() {
return false;
}
@Override
public void connect() throws IOException {
}
@Override
public InputStream getInputStream() throws IOException {
return super.getInputStream();
}
}
步骤二:创建流协议处理程序:HttpURLStreamHandler
public class HttpURLStreamHandler extends URLStreamHandler{
@Override
protected URLConnection openConnection(URL u) throws IOException {
return new HttpURLConnectionImpl(u);
}
}
参照步骤二可以继续创建https协议的HttpURLConnection实现类:HttpsURLConnectionImpl 和 流处理程序:HttpsURLStreamHandler
public class HttpsURLConnectionImpl extends HttpsURLConnection{
protected HttpsURLConnectionImpl(URL url) {
super(url);
}
@Override
public String getCipherSuite() {
return null;
}
@Override
public Certificate[] getLocalCertificates() {
return null;
}
@Override
public Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {
return null;
}
@Override
public void disconnect() {
}
@Override
public boolean usingProxy() {
return false;
}
@Override
public void connect() throws IOException {
}
}
public class HttpsURLStreamHandler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL u) throws IOException {
return new HttpsURLConnectionImpl(u);
}
}
步骤三:创建流协议处理程序工厂:URLStreamHandlerFactoryImpl
public class URLStreamHandlerFactoryImpl implements URLStreamHandlerFactory{
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
if(protocol.equals("http"))
return new HttpURLStreamHandler();
else if(protocol.equals("https"))
return new HttpsURLStreamHandler();
return null;
}
}
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactoryImpl());
完成以上四步,我们来测试下:
public class test {
public static void main(String[] args) {
install();
URL url;
try {
url = new URL("http://www.baidu.com");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
System.out.println(httpURLConnection);//输出:com.yzp.net.http.HttpURLConnectionImpl:http://www.baidu.com
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void install(){
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactoryImpl());
}
}
输出的是:com.yzp.net.http.HttpURLConnectionImpl:http://www.baidu.com,不再是默认的:sun.net.www.protocol.http.HttpURLConnection:http://www.baidu.com
以上只是最简单的实现流程,其实可以在各个实现类里做各种复杂的功能。
Demo下载:http://download.youkuaiyun.com/detail/yzpbright/9485428