关于URL.openConnection()得到的连接对象问题

来源:互联网 发布:华一软件 编辑:程序博客网 时间:2024/06/03 20:34

  同学们在使用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);}@Overridepublic void disconnect() {}@Overridepublic boolean usingProxy() {return false;}@Overridepublic void connect() throws IOException {}@Overridepublic InputStream getInputStream() throws IOException {return super.getInputStream();}}

步骤二:创建流协议处理程序:HttpURLStreamHandler

public class HttpURLStreamHandler extends URLStreamHandler{@Overrideprotected 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);}@Overridepublic String getCipherSuite() {return null;}@Overridepublic Certificate[] getLocalCertificates() {return null;}@Overridepublic Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {return null;}@Overridepublic void disconnect() {}@Overridepublic boolean usingProxy() {return false;}@Overridepublic void connect() throws IOException {}}

public class HttpsURLStreamHandler extends URLStreamHandler {@Overrideprotected URLConnection openConnection(URL u) throws IOException {return new HttpsURLConnectionImpl(u);}}


步骤三:创建流协议处理程序工厂:URLStreamHandlerFactoryImpl

public class URLStreamHandlerFactoryImpl implements URLStreamHandlerFactory{@Overridepublic URLStreamHandler createURLStreamHandler(String protocol) {if(protocol.equals("http"))return new HttpURLStreamHandler();else if(protocol.equals("https"))return new HttpsURLStreamHandler();return null;}}


步骤四:在程序启动时,设置URL类的流协议处理程序工厂:

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.csdn.net/detail/yzpbright/9485428


0 0
原创粉丝点击