HttpURLConnection, HttpClient机制分析



HttpClient


httpClient.execute(Method) 直接发送请求并读取响应,而 method.getResponseBody 其实只是从response缓存中进行读取

HttpClient委托HttpConnectionManager管理连接,委托HttpMethodDirector执行方法,其本身是无状态线程安全的。

connectManager分为:

SimpleHttpConnectorManager为默认选项。会复用连接,但是如果host改变了,则会打开新的链接。

MultiThreadedHttpConnectionManager 为每个host作了一个连接池,放在map中,key=hostConfig value = connectPool,每次根据host从池子中获取连接,并复用之

DummyConnectionManager 则不管host,一律重新建立连接


每次new HttpClient()会新建socket,可以通过 commons-pool,自行实现连接池:

[java]  view plain copy
  1. public class PoolableHttpClientFactory implements PoolableObjectFactory {  
  2.       
  3.     private int timeout;  
  4.     public PoolableHttpClientFactory(int timeout) {  
  5.         this.timeout = timeout;  
  6.     }  
  7.   
  8.     public Object makeObject() throws Exception {  
  9.         HttpClient httpClient = new HttpClient();  
  10.         HttpConnectionManagerParams configParams = httpClient.getHttpConnectionManager().getParams();  
  11.         configParams.setConnectionTimeout(timeout);  
  12.         configParams.setSoTimeout(timeout);  
  13.         httpClient.getParams().setConnectionManagerTimeout(timeout);  
  14.         return httpClient;  
  15.     }  
  16.   
  17.     public void destroyObject(Object obj) throws Exception {  
  18.     }  
  19.   
  20.     public boolean validateObject(Object obj) {  
  21.         return true;  
  22.     }  
  23.   
  24.     public void activateObject(Object obj) throws Exception {  
  25.     }  
  26.   
  27.     public void passivateObject(Object obj) throws Exception {  
  28.     }  
  29.   
  30. }  

[java]  view plain copy
  1. ExecutorService s = Executors.newFixedThreadPool(2);  
  2.   
  3. final ObjectPool pool  = new GenericObjectPool(  
  4.         new PoolableHttpClientFactory(2000),   
  5.         10,   
  6.         GenericObjectPool.WHEN_EXHAUSTED_FAIL,   
  7.         300021falsefalse600001060000false);  
  8.   
  9. for(int i = 0; i < 2; ++i)  
  10. s.execute(new Runnable() {  
  11.     public void run() {  
  12.         while(true) {  
  13.             try {  
  14.                 Thread.sleep(new Random().nextInt(500));  
  15.                   
  16.                 PostMethod method = new PostMethod("http://127.0.0.1:8080/index");  
  17.                 HttpClient hc = (HttpClient) pool.borrowObject();  
  18.                 hc.executeMethod(method);  
  19.                 String resp = method.getResponseBodyAsString();  
  20.                 if(resp.indexOf("jack") == -1) System.out.println(resp);  
  21.                   
  22.                 method.releaseConnection();  
  23.                 pool.returnObject(hc);  
  24.             } catch(Exception e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29. });  


TIP ===================

HttpMethod.setParams(HttpMethodParams)指的是“超时时间”这样的连接属性

对于请求参数,PostMethod.addParameter(k,v)  而GetMethod则需要自行组装url了,记得作 URLEncoder.encode()


HttpURLConnection


1、new URL("http://xx.xx").openConnection(); 会打开  sun.net.www.protocol.http.HttpURLConnection,  其conn.connect()函数会从sun.net.www.http.HttpClient内部的静态连接缓冲池中获取HttpClient连接,对应到一个Socket连接。静态连接池是一个HashTable, key = URL, value = HttpClient

2、HttpURLConnection.getInputStream()会返回sun.net.www.protocol.http.HttpURLConnection$HttpInputStream,其connection.getInputStream.close()函数并不关闭Socket,而是将连接还给连接池。



HttpClient


httpClient.execute(Method) 直接发送请求并读取响应,而 method.getResponseBody 其实只是从response缓存中进行读取

HttpClient委托HttpConnectionManager管理连接,委托HttpMethodDirector执行方法,其本身是无状态线程安全的。

connectManager分为:

SimpleHttpConnectorManager为默认选项。会复用连接,但是如果host改变了,则会打开新的链接。

MultiThreadedHttpConnectionManager 为每个host作了一个连接池,放在map中,key=hostConfig value = connectPool,每次根据host从池子中获取连接,并复用之

DummyConnectionManager 则不管host,一律重新建立连接


每次new HttpClient()会新建socket,可以通过 commons-pool,自行实现连接池:

[java]  view plain copy
  1. public class PoolableHttpClientFactory implements PoolableObjectFactory {  
  2.       
  3.     private int timeout;  
  4.     public PoolableHttpClientFactory(int timeout) {  
  5.         this.timeout = timeout;  
  6.     }  
  7.   
  8.     public Object makeObject() throws Exception {  
  9.         HttpClient httpClient = new HttpClient();  
  10.         HttpConnectionManagerParams configParams = httpClient.getHttpConnectionManager().getParams();  
  11.         configParams.setConnectionTimeout(timeout);  
  12.         configParams.setSoTimeout(timeout);  
  13.         httpClient.getParams().setConnectionManagerTimeout(timeout);  
  14.         return httpClient;  
  15.     }  
  16.   
  17.     public void destroyObject(Object obj) throws Exception {  
  18.     }  
  19.   
  20.     public boolean validateObject(Object obj) {  
  21.         return true;  
  22.     }  
  23.   
  24.     public void activateObject(Object obj) throws Exception {  
  25.     }  
  26.   
  27.     public void passivateObject(Object obj) throws Exception {  
  28.     }  
  29.   
  30. }  

[java]  view plain copy
  1. ExecutorService s = Executors.newFixedThreadPool(2);  
  2.   
  3. final ObjectPool pool  = new GenericObjectPool(  
  4.         new PoolableHttpClientFactory(2000),   
  5.         10,   
  6.         GenericObjectPool.WHEN_EXHAUSTED_FAIL,   
  7.         300021falsefalse600001060000false);  
  8.   
  9. for(int i = 0; i < 2; ++i)  
  10. s.execute(new Runnable() {  
  11.     public void run() {  
  12.         while(true) {  
  13.             try {  
  14.                 Thread.sleep(new Random().nextInt(500));  
  15.                   
  16.                 PostMethod method = new PostMethod("http://127.0.0.1:8080/index");  
  17.                 HttpClient hc = (HttpClient) pool.borrowObject();  
  18.                 hc.executeMethod(method);  
  19.                 String resp = method.getResponseBodyAsString();  
  20.                 if(resp.indexOf("jack") == -1) System.out.println(resp);  
  21.                   
  22.                 method.releaseConnection();  
  23.                 pool.returnObject(hc);  
  24.             } catch(Exception e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29. });  


TIP ===================

HttpMethod.setParams(HttpMethodParams)指的是“超时时间”这样的连接属性

对于请求参数,PostMethod.addParameter(k,v)  而GetMethod则需要自行组装url了,记得作 URLEncoder.encode()


HttpURLConnection


1、new URL("http://xx.xx").openConnection(); 会打开  sun.net.www.protocol.http.HttpURLConnection,  其conn.connect()函数会从sun.net.www.http.HttpClient内部的静态连接缓冲池中获取HttpClient连接,对应到一个Socket连接。静态连接池是一个HashTable, key = URL, value = HttpClient

2、HttpURLConnection.getInputStream()会返回sun.net.www.protocol.http.HttpURLConnection$HttpInputStream,其connection.getInputStream.close()函数并不关闭Socket,而是将连接还给连接池。

HttpClient


httpClient.execute(Method) 直接发送请求并读取响应,而 method.getResponseBody 其实只是从response缓存中进行读取

HttpClient委托HttpConnectionManager管理连接,委托HttpMethodDirector执行方法,其本身是无状态线程安全的。

connectManager分为:

SimpleHttpConnectorManager为默认选项。会复用连接,但是如果host改变了,则会打开新的链接。

MultiThreadedHttpConnectionManager 为每个host作了一个连接池,放在map中,key=hostConfig value = connectPool,每次根据host从池子中获取连接,并复用之

DummyConnectionManager 则不管host,一律重新建立连接


每次new HttpClient()会新建socket,可以通过 commons-pool,自行实现连接池:

[java]  view plain copy
  1. public class PoolableHttpClientFactory implements PoolableObjectFactory {  
  2.       
  3.     private int timeout;  
  4.     public PoolableHttpClientFactory(int timeout) {  
  5.         this.timeout = timeout;  
  6.     }  
  7.   
  8.     public Object makeObject() throws Exception {  
  9.         HttpClient httpClient = new HttpClient();  
  10.         HttpConnectionManagerParams configParams = httpClient.getHttpConnectionManager().getParams();  
  11.         configParams.setConnectionTimeout(timeout);  
  12.         configParams.setSoTimeout(timeout);  
  13.         httpClient.getParams().setConnectionManagerTimeout(timeout);  
  14.         return httpClient;  
  15.     }  
  16.   
  17.     public void destroyObject(Object obj) throws Exception {  
  18.     }  
  19.   
  20.     public boolean validateObject(Object obj) {  
  21.         return true;  
  22.     }  
  23.   
  24.     public void activateObject(Object obj) throws Exception {  
  25.     }  
  26.   
  27.     public void passivateObject(Object obj) throws Exception {  
  28.     }  
  29.   
  30. }  

[java]  view plain copy
  1. ExecutorService s = Executors.newFixedThreadPool(2);  
  2.   
  3. final ObjectPool pool  = new GenericObjectPool(  
  4.         new PoolableHttpClientFactory(2000),   
  5.         10,   
  6.         GenericObjectPool.WHEN_EXHAUSTED_FAIL,   
  7.         300021falsefalse600001060000false);  
  8.   
  9. for(int i = 0; i < 2; ++i)  
  10. s.execute(new Runnable() {  
  11.     public void run() {  
  12.         while(true) {  
  13.             try {  
  14.                 Thread.sleep(new Random().nextInt(500));  
  15.                   
  16.                 PostMethod method = new PostMethod("http://127.0.0.1:8080/index");  
  17.                 HttpClient hc = (HttpClient) pool.borrowObject();  
  18.                 hc.executeMethod(method);  
  19.                 String resp = method.getResponseBodyAsString();  
  20.                 if(resp.indexOf("jack") == -1) System.out.println(resp);  
  21.                   
  22.                 method.releaseConnection();  
  23.                 pool.returnObject(hc);  
  24.             } catch(Exception e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29. });  


TIP ===================

HttpMethod.setParams(HttpMethodParams)指的是“超时时间”这样的连接属性

对于请求参数,PostMethod.addParameter(k,v)  而GetMethod则需要自行组装url了,记得作 URLEncoder.encode()


HttpURLConnection


1、new URL("http://xx.xx").openConnection(); 会打开  sun.net.www.protocol.http.HttpURLConnection,  其conn.connect()函数会从sun.net.www.http.HttpClient内部的静态连接缓冲池中获取HttpClient连接,对应到一个Socket连接。静态连接池是一个HashTable, key = URL, value = HttpClient

2、HttpURLConnection.getInputStream()会返回sun.net.www.protocol.http.HttpURLConnection$HttpInputStream,其connection.getInputStream.close()函数并不关闭Socket,而是将连接还给连接池。




HttpClient


httpClient.execute(Method) 直接发送请求并读取响应,而 method.getResponseBody 其实只是从response缓存中进行读取

HttpClient委托HttpConnectionManager管理连接,委托HttpMethodDirector执行方法,其本身是无状态线程安全的。

connectManager分为:

SimpleHttpConnectorManager为默认选项。会复用连接,但是如果host改变了,则会打开新的链接。

MultiThreadedHttpConnectionManager 为每个host作了一个连接池,放在map中,key=hostConfig value = connectPool,每次根据host从池子中获取连接,并复用之

DummyConnectionManager 则不管host,一律重新建立连接


每次new HttpClient()会新建socket,可以通过 commons-pool,自行实现连接池:

[java]  view plain copy
  1. public class PoolableHttpClientFactory implements PoolableObjectFactory {  
  2.       
  3.     private int timeout;  
  4.     public PoolableHttpClientFactory(int timeout) {  
  5.         this.timeout = timeout;  
  6.     }  
  7.   
  8.     public Object makeObject() throws Exception {  
  9.         HttpClient httpClient = new HttpClient();  
  10.         HttpConnectionManagerParams configParams = httpClient.getHttpConnectionManager().getParams();  
  11.         configParams.setConnectionTimeout(timeout);  
  12.         configParams.setSoTimeout(timeout);  
  13.         httpClient.getParams().setConnectionManagerTimeout(timeout);  
  14.         return httpClient;  
  15.     }  
  16.   
  17.     public void destroyObject(Object obj) throws Exception {  
  18.     }  
  19.   
  20.     public boolean validateObject(Object obj) {  
  21.         return true;  
  22.     }  
  23.   
  24.     public void activateObject(Object obj) throws Exception {  
  25.     }  
  26.   
  27.     public void passivateObject(Object obj) throws Exception {  
  28.     }  
  29.   
  30. }  

[java]  view plain copy
  1. ExecutorService s = Executors.newFixedThreadPool(2);  
  2.   
  3. final ObjectPool pool  = new GenericObjectPool(  
  4.         new PoolableHttpClientFactory(2000),   
  5.         10,   
  6.         GenericObjectPool.WHEN_EXHAUSTED_FAIL,   
  7.         300021falsefalse600001060000false);  
  8.   
  9. for(int i = 0; i < 2; ++i)  
  10. s.execute(new Runnable() {  
  11.     public void run() {  
  12.         while(true) {  
  13.             try {  
  14.                 Thread.sleep(new Random().nextInt(500));  
  15.                   
  16.                 PostMethod method = new PostMethod("http://127.0.0.1:8080/index");  
  17.                 HttpClient hc = (HttpClient) pool.borrowObject();  
  18.                 hc.executeMethod(method);  
  19.                 String resp = method.getResponseBodyAsString();  
  20.                 if(resp.indexOf("jack") == -1) System.out.println(resp);  
  21.                   
  22.                 method.releaseConnection();  
  23.                 pool.returnObject(hc);  
  24.             } catch(Exception e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29. });  


TIP ===================

HttpMethod.setParams(HttpMethodParams)指的是“超时时间”这样的连接属性

对于请求参数,PostMethod.addParameter(k,v)  而GetMethod则需要自行组装url了,记得作 URLEncoder.encode()


HttpURLConnection


1、new URL("http://xx.xx").openConnection(); 会打开  sun.net.www.protocol.http.HttpURLConnection,  其conn.connect()函数会从sun.net.www.http.HttpClient内部的静态连接缓冲池中获取HttpClient连接,对应到一个Socket连接。静态连接池是一个HashTable, key = URL, value = HttpClient

2、HttpURLConnection.getInputStream()会返回sun.net.www.protocol.http.HttpURLConnection$HttpInputStream,其connection.getInputStream.close()函数并不关闭Socket,而是将连接还给连接池。

HttpClient


httpClient.execute(Method) 直接发送请求并读取响应,而 method.getResponseBody 其实只是从response缓存中进行读取

HttpClient委托HttpConnectionManager管理连接,委托HttpMethodDirector执行方法,其本身是无状态线程安全的。

connectManager分为:

SimpleHttpConnectorManager为默认选项。会复用连接,但是如果host改变了,则会打开新的链接。

MultiThreadedHttpConnectionManager 为每个host作了一个连接池,放在map中,key=hostConfig value = connectPool,每次根据host从池子中获取连接,并复用之

DummyConnectionManager 则不管host,一律重新建立连接


每次new HttpClient()会新建socket,可以通过 commons-pool,自行实现连接池:

[java]  view plain copy
  1. public class PoolableHttpClientFactory implements PoolableObjectFactory {  
  2.       
  3.     private int timeout;  
  4.     public PoolableHttpClientFactory(int timeout) {  
  5.         this.timeout = timeout;  
  6.     }  
  7.   
  8.     public Object makeObject() throws Exception {  
  9.         HttpClient httpClient = new HttpClient();  
  10.         HttpConnectionManagerParams configParams = httpClient.getHttpConnectionManager().getParams();  
  11.         configParams.setConnectionTimeout(timeout);  
  12.         configParams.setSoTimeout(timeout);  
  13.         httpClient.getParams().setConnectionManagerTimeout(timeout);  
  14.         return httpClient;  
  15.     }  
  16.   
  17.     public void destroyObject(Object obj) throws Exception {  
  18.     }  
  19.   
  20.     public boolean validateObject(Object obj) {  
  21.         return true;  
  22.     }  
  23.   
  24.     public void activateObject(Object obj) throws Exception {  
  25.     }  
  26.   
  27.     public void passivateObject(Object obj) throws Exception {  
  28.     }  
  29.   
  30. }  

[java]  view plain copy
  1. ExecutorService s = Executors.newFixedThreadPool(2);  
  2.   
  3. final ObjectPool pool  = new GenericObjectPool(  
  4.         new PoolableHttpClientFactory(2000),   
  5.         10,   
  6.         GenericObjectPool.WHEN_EXHAUSTED_FAIL,   
  7.         300021falsefalse600001060000false);  
  8.   
  9. for(int i = 0; i < 2; ++i)  
  10. s.execute(new Runnable() {  
  11.     public void run() {  
  12.         while(true) {  
  13.             try {  
  14.                 Thread.sleep(new Random().nextInt(500));  
  15.                   
  16.                 PostMethod method = new PostMethod("http://127.0.0.1:8080/index");  
  17.                 HttpClient hc = (HttpClient) pool.borrowObject();  
  18.                 hc.executeMethod(method);  
  19.                 String resp = method.getResponseBodyAsString();  
  20.                 if(resp.indexOf("jack") == -1) System.out.println(resp);  
  21.                   
  22.                 method.releaseConnection();  
  23.                 pool.returnObject(hc);  
  24.             } catch(Exception e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29. });  


TIP ===================

HttpMethod.setParams(HttpMethodParams)指的是“超时时间”这样的连接属性

对于请求参数,PostMethod.addParameter(k,v)  而GetMethod则需要自行组装url了,记得作 URLEncoder.encode()


HttpURLConnection


1、new URL("http://xx.xx").openConnection(); 会打开  sun.net.www.protocol.http.HttpURLConnection,  其conn.connect()函数会从sun.net.www.http.HttpClient内部的静态连接缓冲池中获取HttpClient连接,对应到一个Socket连接。静态连接池是一个HashTable, key = URL, value = HttpClient

2、HttpURLConnection.getInputStream()会返回sun.net.www.protocol.http.HttpURLConnection$HttpInputStream,其connection.getInputStream.close()函数并不关闭Socket,而是将连接还给连接池。

HttpClient


httpClient.execute(Method) 直接发送请求并读取响应,而 method.getResponseBody 其实只是从response缓存中进行读取

HttpClient委托HttpConnectionManager管理连接,委托HttpMethodDirector执行方法,其本身是无状态线程安全的。

connectManager分为:

SimpleHttpConnectorManager为默认选项。会复用连接,但是如果host改变了,则会打开新的链接。

MultiThreadedHttpConnectionManager 为每个host作了一个连接池,放在map中,key=hostConfig value = connectPool,每次根据host从池子中获取连接,并复用之

DummyConnectionManager 则不管host,一律重新建立连接


每次new HttpClient()会新建socket,可以通过 commons-pool,自行实现连接池:

[java]  view plain copy
  1. public class PoolableHttpClientFactory implements PoolableObjectFactory {  
  2.       
  3.     private int timeout;  
  4.     public PoolableHttpClientFactory(int timeout) {  
  5.         this.timeout = timeout;  
  6.     }  
  7.   
  8.     public Object makeObject() throws Exception {  
  9.         HttpClient httpClient = new HttpClient();  
  10.         HttpConnectionManagerParams configParams = httpClient.getHttpConnectionManager().getParams();  
  11.         configParams.setConnectionTimeout(timeout);  
  12.         configParams.setSoTimeout(timeout);  
  13.         httpClient.getParams().setConnectionManagerTimeout(timeout);  
  14.         return httpClient;  
  15.     }  
  16.   
  17.     public void destroyObject(Object obj) throws Exception {  
  18.     }  
  19.   
  20.     public boolean validateObject(Object obj) {  
  21.         return true;  
  22.     }  
  23.   
  24.     public void activateObject(Object obj) throws Exception {  
  25.     }  
  26.   
  27.     public void passivateObject(Object obj) throws Exception {  
  28.     }  
  29.   
  30. }  

[java]  view plain copy
  1. ExecutorService s = Executors.newFixedThreadPool(2);  
  2.   
  3. final ObjectPool pool  = new GenericObjectPool(  
  4.         new PoolableHttpClientFactory(2000),   
  5.         10,   
  6.         GenericObjectPool.WHEN_EXHAUSTED_FAIL,   
  7.         300021falsefalse600001060000false);  
  8.   
  9. for(int i = 0; i < 2; ++i)  
  10. s.execute(new Runnable() {  
  11.     public void run() {  
  12.         while(true) {  
  13.             try {  
  14.                 Thread.sleep(new Random().nextInt(500));  
  15.                   
  16.                 PostMethod method = new PostMethod("http://127.0.0.1:8080/index");  
  17.                 HttpClient hc = (HttpClient) pool.borrowObject();  
  18.                 hc.executeMethod(method);  
  19.                 String resp = method.getResponseBodyAsString();  
  20.                 if(resp.indexOf("jack") == -1) System.out.println(resp);  
  21.                   
  22.                 method.releaseConnection();  
  23.                 pool.returnObject(hc);  
  24.             } catch(Exception e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29. });  


TIP ===================

HttpMethod.setParams(HttpMethodParams)指的是“超时时间”这样的连接属性

对于请求参数,PostMethod.addParameter(k,v)  而GetMethod则需要自行组装url了,记得作 URLEncoder.encode()


HttpURLConnection


1、new URL("http://xx.xx").openConnection(); 会打开  sun.net.www.protocol.http.HttpURLConnection,  其conn.connect()函数会从sun.net.www.http.HttpClient内部的静态连接缓冲池中获取HttpClient连接,对应到一个Socket连接。静态连接池是一个HashTable, key = URL, value = HttpClient

2、HttpURLConnection.getInputStream()会返回sun.net.www.protocol.http.HttpURLConnection$HttpInputStream,其connection.getInputStream.close()函数并不关闭Socket,而是将连接还给连接池。

你可能感兴趣的:(HttpURLConnection, HttpClient机制分析)