HttpUrlConnection底层实现和关于java host绑定ip即时生效的设置及分析

最近有个需求需要对于获取URL页面进行host绑定并且立即生效,在java里面实现可以用代理服务器来实现:因为在测试环境下可能需要通过绑定来访问测试环境的应用
实现代码如下:
 
    public static String getResponseText(String queryUrl,String host,String ip) { //queryUrl,完整的url,host和ip需要绑定的host和ip
       InputStream is = null;
       BufferedReader br = null;
       StringBuffer res = new StringBuffer();
       try {
           HttpURLConnection httpUrlConn = null;
           URL url = new URL(queryUrl);
           if(ip!=null){
               String str[] = ip.split("\\.");
               byte[] b =new byte[str.length];
               for(int i=0,len=str.length;i<len;i++){
                   b[i] = (byte)(Integer.parseInt(str[i],10));
               }
                Proxy proxy = new Proxy(Proxy.Type.HTTP,
                new InetSocketAddress(InetAddress.getByAddress(b), 80));  //b是绑定的ip,生成proxy代理对象,因为http底层是socket实现,
                httpUrlConn = (HttpURLConnection) url
                .openConnection(proxy);
           }else{
                httpUrlConn = (HttpURLConnection) url
                        .openConnection(); 
           }
           httpUrlConn.setRequestMethod("GET");
           httpUrlConn.setDoOutput(true);
           httpUrlConn.setConnectTimeout(2000);
           httpUrlConn.setReadTimeout(2000);
           httpUrlConn.setDefaultUseCaches(false);
           httpUrlConn.setUseCaches(false);
 
           is = httpUrlConn.getInputStream();
 
 
那么底层对于proxy对象到底是怎么处理,底层的socket实现到底怎么样,带着这个疑惑看了下jdk的rt.jar对于这块的处理
httpUrlConn = (HttpURLConnection) url.openConnection(proxy)
 
java.net.URL类里面的openConnection方法:
public URLConnection openConnection(Proxy proxy){
   …
   return handler.openConnection(this, proxy); Handler是sun.net.www.protocol.http.Handler.java类,继承java.net. URLStreamHandler.java类,用来处理http连接请求响应的。
}
 
Handler的方法:
protected java.net.URLConnection openConnection(URL u, Proxy p)
        throws IOException {
        return new HttpURLConnection(u, p, this);
    }
 
只是简单的生成sun.net.www.protocl.http.HttpURLConnection对象,并进行初始化
protected HttpURLConnection(URL u, Proxy p, Handler handler) {
        super(u);
        requests = new MessageHeader();  请求头信息生成类
        responses = new MessageHeader(); 响应头信息解析类
        this.handler = handler; 
        instProxy = p;  代理服务器对象
        cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
            public Object run() {
                return CookieHandler.getDefault();
            }
        });
        cacheHandler = (ResponseCache)java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
            public Object run() {
                return ResponseCache.getDefault();
            }
        });
    }
  
 
最终在httpUrlConn.getInputStream();才进行socket连接,发送http请求,解析http响应信息。具体过程如下:
 
sun.net.www.protocl.http.HttpURLConnection.java的getInputStream方法:
 
public synchronized InputStream getInputStream() throws IOException {
   
     ...socket连接
     connect();
     ...
     ps = (PrintStream)http.getOutputStream(); 获得输出流,打开连接之后已经生成。
 
       if (!streaming()) {
             writeRequests();  输出http请求头信息
       }
     ...
     http.parseHTTP(responses, pi, this);  解析响应信息
                if(logger.isLoggable(Level.FINEST)) {
                    logger.fine(responses.toString());
                }
                inputStream = http.getInputStream();  获得输入流
}
 
其中connect()调用方法链:
plainConnect(){
...
                Proxy p = null;
                if (sel != null) {
                    URI uri = sun.net.www.ParseUtil.toURI(url);
                    Iterator<Proxy> it = sel.select(uri).iterator();
                    while (it.hasNext()) {
                        p = it.next();
                        try {
                            if (!failedOnce) {
                                http = getNewHttpClient(url, p, connectTimeout);
...
}
 
getNewHttpClient(){
...
        return HttpClient.New(url, p, connectTimeout, useCache);
...
}
 
下面跟进去最终建立socket连接的代码:
sun.net.www.http.HttpClient.java的openServer()方法建立socket连接:
 
    protected synchronized void openServer() throws IOException {
            ...
            if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) {
                sun.net.www.URLConnection.setProxiedHost(host);
                if (security != null) {
                    security.checkConnect(host, port);
                }
                pri
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值