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

1 篇文章 0 订阅

  同学们在使用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类的流协议处理程序工厂:

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


  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值